home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v17n03 / ucrasm.exe / SOURCE.EXE / STDLIB.TXT < prev    next >
Encoding:
Text File  |  1991-11-08  |  181.1 KB  |  5,529 lines

  1. ***************************************************************************
  2. ***************************************************************************
  3.  
  4.  
  5.  
  6. The UCR Standard Library for Assembly Language Programmers,
  7. Written By Randall Hyde and others, is
  8.  
  9.   sssssss      ss     ss       ss       sssssss     sssssss
  10.   ss           ss     ss      ssss      ss    ss    ss
  11.   ss           ss     ss     ss  ss     ss    ss    ss
  12.   sssssss      sssssssss    ssssssss    sssssss     sssss        ssssssss
  13.        ss      ss     ss    ss    ss    ss  ss      ss
  14.        ss      ss     ss    ss    ss    ss   ss     ss
  15.   sssssss      ss     ss    ss    ss    ss    ss    sssssss
  16.  
  17.  
  18.  
  19.   ww                  ww       ww       sssssss     sssssss
  20.    ww                ww       wwww      ss    ss    ss
  21.     ww      ww      ww       ww  ww     ss    ss    ss
  22.      ww    wwww    ww       wwwwwwww    sssssss     sssss
  23.       ww  ww  ww  ww        ww    ww    ss  ss      ss
  24.        wwww    wwww         ww    ww    ss   ss     ss
  25.         ww      ww          ww    ww    ss    ss    sssssss
  26.  
  27.  
  28.  
  29.  
  30. We do not want any registration fees for this software.
  31.  
  32. Now for the catch...  It is more blessed to give than to receive.  
  33. If this software saves you time and effort and you enjoy using it, 
  34. our lives will be enriched knowing that others have appreciated our work.  
  35. We would like to share this wonderful feeling with you.  If you like this 
  36. software and use it, we would like you to contribute at least one routine to 
  37. the library.  Perhaps you think this library has some neat-o routines in it.  
  38. Imagine how nice it would become if everyone used their imagination to 
  39. contribute something useful to it.
  40.  
  41. We hereby release this software to the public domain.  You can use it in any
  42. way you see fit.  However, we would appreciate it if you share this software 
  43. with others as much as it has been shared it with you.  That is not to suggest
  44. that you give away software you have written with this package (We're not 
  45. quite as crazy as Richard Stallman, bless his heart), but if someone else would 
  46. like a copy of this library, please help them out.  Naturally, we would be 
  47. tickeled pink to receive credit in software that uses these routines (which is 
  48. the honorable thing to do) but we understand the way many corporations operate 
  49. and won't be terribly put off if you use it without giving due credit.  
  50.  
  51. Enjoy!
  52.  
  53. If you have comments, bug reports, new code to contribute, etc., you can 
  54. reach us through:
  55.  
  56.         rhyde                (On BIX).
  57.         rhyde@ucrmath.ucr.edu        (On Internet).
  58.  
  59. or
  60.  
  61.         Randall Hyde
  62.         Dept of Computer Science
  63.         122 University Office Bldg
  64.         University of California
  65.         Riverside, Ca. 92521
  66.  
  67.  
  68. COMMENTS ABOUT THE CODE:
  69. ************************
  70.  
  71. Please don't expect super optimal code here.  Most of it is fairly mediocre 
  72. (from a size/speed point of view).  Hopefully, you'll agree, it's the idea 
  73. that counts.  If you do not like something I have done, you have got the 
  74. sources -- have at it.  (Of course, it would be appreciated if you would
  75. send any modifications to one of the E-MAIL addresses above.)
  76.  
  77.  
  78. COMMENTS ABOUT THIS DOCUMENTATION:
  79. **********************************
  80.  
  81. You will have to forgive us for the inconsistent style appearing throughout
  82. this document.  Keep in mind that this document has been prepared by many
  83. different people.  Keeping the styles consistent is a time consuming and
  84. difficult task.
  85.  
  86. Whenever a routine's description claims that the flags are not affected,
  87. you should not interpret this to mean that the routine preserves the flags.
  88. Most routines do *not* preserve any of the flags.  Such a statement simply
  89. means that the routine does not *explicitly* return a value in one (or more)
  90. of the flag bits.
  91.  
  92. Note that proper credit has been given to the author of each of the various
  93. routines appearing in this library *except* for those written by Randall
  94. Hyde.  All routines without an author by-line were probably written by
  95. Randall Hyde (unless we screwed up somewhere and forgot to put a name
  96. in the documentation).  Most of these routines were tested and documented
  97. by various students in Randy Hyde's CS 13 (assembly language) and CS 191X /
  98. CS 185 courses (Commercial Software Development).  There are too many names
  99. to mention here, but these students definitely deserve the credit for locating
  100. numerous bugs in the code, providing many suggestions, and doing other work.
  101.  
  102.  
  103. =============================================================================
  104.  
  105. Version History:
  106.  
  107. Version 0.0-     Initial release as "Randy Hyde's Standard Library for 80x86
  108.         Assembly Language programmers"
  109.  
  110. Version 1.0-    Initial release as "UCR Standard Library..."  CS 191X
  111.         students did some testing and documentation in this release.
  112.  
  113. Version 2.0-    More testing on several routines.  Added floating point
  114.         library and several other routines.
  115.  
  116. Version 2.1-    Fixed *MAJOR* bugs in floating point package.  Added
  117. 11-1-91        several new routines.  Included new "TEST" files with
  118.         the library.  Also included SHELL.ASM file inadvertently
  119.         left out of Version 2.0.
  120.  
  121. ==============================================================================
  122.  
  123.  
  124. ROUTINES WE WOULD LIKE TO HAVE:
  125. *******************************
  126.  
  127. If you're interested in adding some routines to this
  128. package, GREAT!  Here are some suggestions.
  129.  
  130. 1) Routines which manipulate directories (read/write/etc.)
  131. 2) A regular expression interpreter.
  132. 3) Length-prefixed strings package.
  133. 4) A graphics package.
  134. 5) An object-oriented programming class library.
  135. 6) Just about anything else appearing in a HLL "standard" library.
  136. If you've got any ideas, we would  love to discuss them with you.  The best
  137. way to reach us is through the E-MAIL addresses above.
  138.  
  139.  
  140. MISSING ROUTINES TO BE SUPPLIED IN THE FUTURE:
  141. **********************************************
  142.  
  143. Character strings:
  144. trim-        Removes trailing blanks from a string.
  145. blkdel-        Removes leading blanks from a string.
  146. translit-    Transliterates characters in a string based on a translation
  147.         table.
  148.  
  149.  
  150. Pattern matching and character sets:
  151. span-        Skips through a sequence of characters in a string which
  152.         belong to a character set.
  153. break-        Skips through a sequence of characters in a string which do not
  154.         belong to a character set.
  155. any-        Skips over a character if it is a member of a set.
  156. notany-        Skips over a character in a string if it is not a member
  157.         of a set.
  158. skip-        Skips "n" characters in the string.
  159. tab-        Matches up to the nth character in a string.
  160. rtab-        Matches up to the nth character from the end of a string.
  161. pos-        Matches if we are currently at the nth position in a string.
  162. rpos-        Matches if we are at the nth position from the end of the
  163.         string.
  164. mark-        Marks a position in a string during pattern matching
  165. grab-        Copies everything from the last mark and creates a new string 
  166.         on the stack from this substring.
  167. match-        Initialize pattern matching system.
  168. alternate-    Try an alternative if the current pattern does not match.
  169. arb-        Skip over an arbitrary number of characters in a match.
  170. replace-    Replace a substring from the last mark to the current 
  171.         position with some other string.
  172. fail-        Force a match failure.
  173. succeed-    Force a match success.
  174.  
  175.  
  176.     Memory Manager Package
  177. Memavail-    Largest block of free memory available on the heap.
  178. Memfree-    Total amount of free space on the heap.
  179. BlockSize-    Returns the size of the memory block which es:di points at.
  180.  
  181.  
  182.     Structured Array Package
  183. aryalloc-    Allocate storage for a single dimension structured array.
  184. ary2alloc-    Allocate storage for a two dimension structured array.
  185. ary3alloc-    Allocate storage for a three dimension structured array.
  186. arynalloc-    Allocate storage for an n-dimensional structured array.
  187. aryaccess-    Access an element of a structured array.
  188. ary2access-    Access an element of a two-dimension structured array.
  189. ary3access-    Access an element of a three-dimension structured array.
  190. arynaccess-    Access an element of an n-dimensional structured array.
  191. copyarray-    Copy the elements of one structured array to another.
  192. duparray-    Duplicate a structured array on the heap.
  193. redim-        Redimension a structured array.
  194. aryfill-    Initialize an array with a list of values.
  195. cmpary-        Compares two structured arrays to see if they are equal.
  196.  
  197.  
  198.     Process Manager Package
  199. CoCall-        Call a coroutine.  
  200. CoInit-        Initialize a coroutine.
  201. CoRet-        Quit a coroutine.
  202.  
  203.  
  204. HOW TO USE THE STANDARD LIBRARY:
  205. ********************************
  206.  
  207. When you are ready to begin programming with the library, you should
  208. copy the shell.asm file, provided in the package, to another file in
  209. which you will be working, i.e. myprog.asm.  The shell.asm file sets
  210. up the machine (segments, etc.) as the UCR Standard Library expects
  211. them.  Results are undefined for other setups.  Therefore, I strongly
  212. suggest, that when you begin using these routines, you follow the
  213. shell.asm format.  Later, when you are familiar with the software,
  214. you may wish to create your own shell.asm file, but it is wise to
  215. initially use the one provided.  The shell.asm file has comments which
  216. tell you where to place your code, variables, etc.
  217.  
  218. There is an include file, stdlib.a (stdlib.a6 for MASM 6.0 users), which
  219. you should include in every assembly you perform which calls the stdlib
  220. routines.  SHELL.ASM already includes this file.  *YOU MUST PLACE THE
  221. INCLUDE STATEMENT OUTSIDE OF ANY SEGMENTS IN YOUR PROGRAM*.  Preferably
  222. as the first line of your program (just like SHELL.ASM).  If you place
  223. this include directive inside a segment, certain assemblers/linkers
  224. (especially MASM) will not properly assemble and link your programs.
  225. They will assemble and link without error, but the resulting program
  226. will not execute correctly.
  227.  
  228. The STDLIB.A file contains macros you can use to call each of the routines
  229. in the standard library.  For example, to call PRINTF you would use the
  230. statement
  231.         printf
  232.         db    "format string",0
  233.         db    other,vars
  234.  
  235. rather than "calling" printf.  Printf is actually a macro, you cannot call
  236. it directly (all of the standard library routines have names like "sl_printf"
  237. and the macro issues a call to the appropriate routine).  These macros have
  238. two main purposes-- first, the differentiate calls to the standard library
  239. routines (i.e., no "call" instruction is the difference); and second, they
  240. contain some extra code to perform "smart linking" with MASM 5.1 & earlier,
  241. TASM, and OPTASM.  MASM 6.0 supports a new directive, extrndef, which
  242. eliminates the need for this extra code, but the extra code works nonetheless.
  243. There is a special include file, STDLIB.A6, for MASM 6.0 users which is
  244. smaller and, therefore, speeds up assemblies and consumes less memory
  245. during assembly.
  246.  
  247. All of the standard library routines, and most of their local data values,
  248. are in a segment named "stdlib".  You should not create such a segment unless
  249. you plan on adding new routines to the standard library.
  250.  
  251.  
  252. HOW THE STANDARD LIBRARY IS ORGANIZED:
  253. **************************************
  254.  
  255. In the next several pages are the documentation spec sheets for each of the
  256. standard library routines.  The routines are listed by category.  The listing
  257. of the categories and their order in the documentation is below.
  258.  
  259.     Standard Input Routines
  260.     Standard Output Routines
  261.     Conversion Routines
  262.     Utility Routines
  263.     String Handling Routines
  264.     Memory Management Routines
  265.     Character Set Routines
  266.     Floating Point Routines
  267.  
  268. In addition, at the beginning of each of the category is a brief
  269. discussion of the purpose of its routines.
  270.  
  271.  
  272.  
  273.  
  274.  
  275. Character Input Routines
  276. ------------------------
  277.  
  278.  
  279.     The character input routines take input from either a standard
  280. device (keyboard, etc.) or a standard library.  After the character input
  281. routines receive the characters they either place the characters on the stack
  282. and/or return.  The character input routines work similar to the "C" character
  283. input routines.
  284.  
  285.  
  286.  
  287. Routine:  Getc
  288. --------------
  289.  
  290.  
  291. Category:             Character Input Routine
  292.  
  293.  
  294. Registers on Entry:   None
  295.  
  296.  
  297. Registers on Return:  AL- Character from input device.
  298.                       AH- 0 if eof, 1 if not eof.
  299.  
  300.  
  301. Flags Affected:       Carry- 0 if no error, 1 if error.  If error occurs, AX
  302.                              contains DOS error code.
  303.  
  304.  
  305. Example of Usage:  
  306.                       getc
  307.                       mov     KbdChar, al
  308.                       putc
  309.  
  310.  
  311. Description:  This routine reads a character from the standard input device.
  312.               This call is synchronous, that is, it does not return until a
  313.               character is available.  The Default input device is DOS
  314.               standard input.
  315.  
  316.               Getc returns two types of values: extended ASCII (codes 1-255)
  317.               and IBM keyboard scan codes.  If Getc returns a non-zero value,
  318.               you may interpret this value as an ASCII character.  If Getc
  319.               returns zero, you must call Getc again to get the actual
  320.               keypress.
  321.  
  322.               The second call returns an IBM PC keyboard scan code.
  323.  
  324.               Since the user may redirect input from the DOS command line,
  325.               there is the possibility of encountering end-of-file (eof)
  326.               when calling getc.  Getc uses the AH register to return eof
  327.               status.  AH contains the number of characters actually read
  328.               from the standard input device.  If it returns one, then
  329.               you've got a valid character.  If it returns zero, you've
  330.               reached end of file.  Note that pressing control-z forces an
  331.               end of file condition when reading data from the keyboard.
  332.  
  333.               This routine returns the carry flag clear if the operation
  334.               was successful.  It returns the carry flag set if some sort
  335.               of error occurred while reading the character.  Note that eof
  336.               is not an error condition.  Upon reaching the end of file,
  337.               Getc returns with the carry flag clear.  If getc is seen from
  338.               a file the control-z is not seen as an end-of-file marker,
  339.               but just read in as a character of the file.
  340.  
  341.               Control-c if read from a keyboard device aborts the program.
  342.               However if when reading something other than a keyboard
  343.               (files, serial ports), control-c from the input source
  344.               returns control-c.  However when pressing control-break
  345.               the program will abort regardless of the input source.
  346.  
  347.               Regarding CR/LF, if the input is from a device, (eg. keyboard
  348.               serial port) getc returns whatever that device driver returns,
  349.               (generally CR without a LF).  However if the input is from
  350.               a file, getc stripes a single LF if it immediately follows
  351.               the CR.
  352.  
  353.               When using getc files operate in "cooked" mode.  While
  354.               devices operate in "pseudo-cooked" mode, which means no
  355.               buffering, no CR -> CR/LF, but it handles control-c, and
  356.               control-z.
  357.  
  358.           See the sources for more information about GETC's internal
  359.           operation.
  360.  
  361. Include:    stdlib.a   
  362.  
  363.  
  364.  
  365.  
  366. Routine:   GetcStdIn
  367. --------------------
  368.  
  369.  
  370. Category:             Character Input Routine
  371.  
  372. Register on entry:    None.
  373.  
  374. Register on return:   AL- Character from input device.
  375.  
  376. Flags affected:       AH- 0 if eof, 1 if not eof.
  377.                       Carry- 0 if no error, 1 if error
  378.                       (AX contains DOS error code if error occurs).
  379.  
  380.  
  381. Example of Usage:   
  382.                       GetcStdIn
  383.                       mov     InputChr, al
  384.                       putc
  385.  
  386.  
  387. Description:    This routine reads a character from the DOS standard input
  388.                 device.  This call is synchronous, that is, it does not return
  389.                 until a character is available.  See the description of Getc
  390.                 above for more details.
  391.  
  392.         The difference between Getc and GetcStdIn is that your
  393.         program can redirect Getc using other calls in this library.
  394.         GetcStdIn calls DOS directly without going through this
  395.         redirection mechanism.
  396.  
  397.  
  398. Include:        stdlib.a
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405. Routine:   GetcBIOS
  406. -------------------
  407.  
  408.  
  409. Category:             Character Input Routine
  410.  
  411. Register on entry:    None
  412.  
  413. Register on return:   AL- Character from the keyboard.
  414.  
  415. Flags affected:       AH- 1 (always).  Carry- 0 (always).
  416.  
  417. Example of Usage:   
  418.                       GetcBIOS
  419.                       mov     CharRead, al
  420.                       putc
  421.  
  422.  
  423. Description:   This routine reads a character from the keyboard.  This call is
  424.                synchronous, that is it does not return until a character is
  425.                available.
  426.  
  427.         Note that there is no special character processing.  This
  428.         code does *not* check for EOF, control-C, or anything
  429.         else like that.
  430.  
  431.  
  432.  
  433. Include:        stdlib.a
  434.  
  435.  
  436.  
  437. Routine:  SetInAdrs
  438. -------------------
  439.  
  440. Category:               Character Input Routine
  441.  
  442. Registers on Entry:     ES:DI - address of new input routine
  443.  
  444. Registers on return:    None 
  445.  
  446. Flags affected:
  447.  
  448. Examples of Usage:
  449.  
  450.                         mov     es, seg NewInputRoutine
  451.                         mov     di, offset NewInputRoutine
  452.                         SetInAdrs
  453.  
  454.  
  455.  
  456.                         les     di, RoutinePtr
  457.                         SetInAdrs
  458.  
  459.  
  460. Description:    This routine redirects the stdlib standard input so that it 
  461.                 calls the routine who's address you pass in es:di.  The
  462.         routine (whose address appears in es:di) should be a "getc"
  463.         routine which reads a character from somewhere and returns
  464.         that character in AL.  It should also return EOF status in
  465.         the AH register and error status in the carry flag (see
  466.         the description of GETC for more details).
  467.  
  468.  
  469. Include:                stdlib.a
  470.  
  471.  
  472.  
  473.  
  474.  
  475. Routine:   GetInAdrs
  476. --------------------
  477.  
  478. Category:             Character Input Routine
  479.  
  480. Register on entry:    None
  481.  
  482. Register on return:   ES:DI - address of current input routine (called by Getc).
  483.  
  484. Flags affected:       None
  485.  
  486.  
  487. Example of Usage:   
  488.                       GetInAdrs
  489.                       mov     word ptr SaveInAdrs, di
  490.                       mov     word ptr SaveInAdrs+2, es
  491.  
  492.  
  493. Description:   You can use this function to get the address of the current
  494.                input routine, perhaps so you can save it or see if it is
  495.                currently pointing at some particular piece of code.
  496.                If you want to temporarily redirect the input and then restore
  497.                the original input or outline, consider using
  498.                PushInAdrs/PopInAdrs described later.
  499.  
  500.  
  501. Include:        stdlib.a
  502.  
  503.  
  504.  
  505. Routine:   PushInAdrs
  506. ---------------------
  507.  
  508. Category:             Character Input Routine
  509.  
  510. Register on entry:    ES:DI - Address of new input routine.
  511.  
  512. Register on return:   Carry=0 if operation successful.
  513.                       Carry=1 if there were already 16 items on the stack.
  514.                          
  515. Example of Usage:   
  516.                       mov     es, seg NewInputRoutine
  517.                       mov     di, offset NewInputRoutine
  518.                       PushInAdrs
  519.                         .
  520.                         .
  521.                         .
  522.                       les     di, RoutinePtr
  523.                       PushInAdrs
  524.  
  525.  
  526. Description:   This routine "pushes" the current input address onto an
  527.                internal stack and then copies the value in es:di into the
  528.                current input routine pointer.  The PushInAdrs and PopInAdrs
  529.                routines let you easily save and redirect the standard output
  530.                and then restore the original output routine address later on.
  531.                If you attempt to push more than 16 items on the stack,
  532.                PushInAdrs will ignore your request and return with the
  533.                carry flag set.  If PushInAdrs is successful, it will
  534.                return with the carry flag clear.
  535.  
  536.  
  537. Include:    stdlib.a
  538.  
  539.  
  540.  
  541.  
  542.  
  543. Routine:   PopInAdrs
  544. --------------------
  545.  
  546. Category:             Character Input Routine
  547.  
  548. Register on entry:    None
  549.  
  550. Register on return:   ES:DI - Points at the previous stdout routine before
  551.                       the pop.
  552.  
  553. Example of Usage:   
  554.                       mov     es, seg NewInRoutine
  555.                       mov     di, offset NewInputRoutine
  556.                       PushInAdrs
  557.                         .
  558.                         .
  559.                         .
  560.                       PopInAdrs
  561.  
  562.  
  563. Description:   PopInAdrs undoes the effects of PushInAdrs.  It pops an item
  564.                off the internal stack and stores it into the input routine
  565.                pointer.  The previous value in the output pointer is returned
  566.                in es:di.
  567.  
  568. Include:    stdlib.a
  569.  
  570.  
  571.  
  572.  
  573.  
  574. Routine:  Gets, Getsm
  575. ---------------------
  576.  
  577. Category:             Character Input Routine
  578.  
  579. Register on entry:    ES:DI- Pointer to input buffer (gets only).
  580.  
  581. Register on return:   ES:DI - address of input of text.
  582.                       carry-  0 if no error, 1 if error.
  583.                       If error, AX contains: 0- End of
  584.                       file encountered in middle of
  585.                       string.  1- Memory allocation error (getsm only).
  586.                       Other- DOS error code.
  587.  
  588.  
  589. Flags affected:       None
  590.  
  591. Example of usage:    
  592.                       getsm           ;Read a string from the
  593.                                       ;keyboard
  594.                       puts            ;Print it
  595.                       putcr           ;Print a new line
  596.                       free            ;Deallocate storage for
  597.                                       ;string.
  598.  
  599.               mov    di, seg buffer
  600.               mov    es, di
  601.               lea    di, buffer
  602.               gets
  603.               puts
  604.               putcr
  605.  
  606.  
  607. Description:       Reads a line of text from the stdlib standard input device.
  608.         You must pass a pointer to the recipient buffer in es:di to
  609.         the GETS routine.  GETSM automatically allocates storage for
  610.         the string on the heap (up to 256 bytes) and returns a pointer
  611.         to this block in es:di.
  612.  
  613.         Gets(m) returns all characters typed by the user except for the
  614.         carriage return (ENTER) key code.  These routines return a
  615.         zero-terminated string (with es:di pointing at the string).
  616.         Exactly how Gets(m) treats the incoming data depends upon
  617.         the source device, however, you can usually count on Gets(m)
  618.         properly handling backspace (erases previous character),
  619.         escape (erase entire line), and ENTER (accept current line).
  620.  
  621.         Other keys may affect Gets(m) as well.  For example, Gets(m),
  622.         by default, calls Getc which, in turn, usually calls DOS'
  623.         standard input routine.  If you type control-C or break while
  624.         read from DOS' standard input it may abort the program.
  625.  
  626.         If an error occurs during input (e.g., EOF encountered in
  627.         the middle of a line) Gets(m) returns the error code in
  628.         AX.  If no error occurs, Gets(m) preserves AX.
  629.  
  630. Include:                  stdlib.a
  631.  
  632.  
  633.  
  634.  
  635.  
  636. Routine:  Scanf
  637. ---------------
  638.  
  639. Category:             Character Input Routine
  640.  
  641. Register on entry:    None
  642.  
  643. Register on return:   None
  644.  
  645. Flags affected:       None
  646.  
  647. Example of usage:   
  648.                       scanf
  649.                       db      "%i  %h  %^s",0
  650.                       dd      i, x, sptr
  651.  
  652. Description:   * Formatted input from stdlib standard input.
  653.                * Similar to C's scanf routine.
  654.                * Converts ASCII to integer, unsigned, character, string, hex,
  655.                  and long values of the above.
  656.                Scanf provides formatted input in a fashion analogous to
  657.                printf's output facilities.  Actually, it turns out that scanf
  658.                is considerably less useful than printf because it doesn't
  659.                provide reasonable error checking facilities (neither does C's
  660.                version of this routine).  But for quick and dirty programs 
  661.                whose input can be controlled in a rigid fashion (or if you're
  662.                willing to live by "garbage in, garbage out")  scanf provides 
  663.                a convenient way to get input from the user.  Like printf, the
  664.                scanf routine expects you to follow the call with a format 
  665.                string and then a list of (far pointer) memory addresses.  The
  666.                items in the scanf format string take the following form: %^f,
  667.                where f represents d, i, x, h, u, c, x, ld, li, lx, or lu.  
  668.                Like printf, the "^" symbol tells scanf that the address
  669.                following the format string is the address of a (far) pointer
  670.                to the data rather than the address of the data location itself.
  671.                By default, scanf automatically skips any leading whitespace 
  672.                before attempting to read a numeric value.  You can instruct
  673.                scanf to skip other characters by placing that character in the
  674.                format string.  For example, the following call instructs scanf
  675.                to read three integers separated by commas (and/or whitespace):
  676.  
  677.                                  scanf  
  678.                   db                "%i,%i,%i",0
  679.                               dd                 i1,i2,i3
  680.  
  681.                Whenever scanf encounters a non-blank character in the format
  682.                string, it will skip that character (including multiple
  683.                occurrences of that character) if it appears next in the input
  684.                stream.  Scanf always calls gets to read a new line of text 
  685.                from stdlib's standard input.  If scanf exhausts the format 
  686.                list, it ignores any remaining characters on the line.  If
  687.                scanf exhausts the input line before processing all of the
  688.                format items, it leaves the remaining variables unchanged.
  689.                Scanf always deallocates the storage allocated by gets.
  690.  
  691.  
  692. Include:                stdlib.a
  693.  
  694.  
  695.  
  696.  
  697. Character Output Routines
  698. -------------------------
  699.  
  700.  
  701. The stdlib character output routines allow you to print to the 
  702. standard output device.  Although the processing of non-ASCII 
  703. characters is undefined, most output devices handle these characters
  704. properly.  In particular, they can handle return, line feed, back space, 
  705. and tab.  
  706.  
  707. Most of the output routines in the standard library output data 
  708. through the Putc routine.  They generally use the AX register upon 
  709. entry and print the character(s) to the standard output device by
  710. calling DOS by default. The  output is redirectable to the 
  711. user-written routine.  However, the PutcBIOS routine prints doesn't 
  712. use DOS.  Instead it uses BIOS routines to print the character in AL 
  713. using the INT command for teletype-like output. 
  714.  
  715. The print routines are similar to those in C, however, they differ
  716. in their implementation. The print routine returns to the address
  717. immediately following the terminating byte, therefore, it is important
  718. to remember to terminate your string with zero or you will print an 
  719. unexpected sequence of characters.
  720.  
  721.  
  722.  
  723. Routine:  Putc
  724. --------------
  725.  
  726. Category:             Character Output Routine
  727.  
  728. Registers on Entry:   AL- character to output
  729.  
  730. Registers on Return:  None
  731.  
  732. Flags affected:       None
  733.  
  734. Example of Usage:
  735.                        mov     al, 'C'
  736.                        putc                    ;Prints "C" to std output.
  737.  
  738.  
  739. Description:  Putc is the primitive character output routine.  Most other
  740.               output routines in the standard library output data through
  741.               this procedure.  It prints the ASCII character in AL register.  
  742.               The processing of control codes is undefined although most output
  743.               routines this routine links to should be able to handle return, 
  744.               line feed, back space, and tab.  By default, this routine calls
  745.               DOS to print the character to the standard output device.  The
  746.               output is redirectable to to user-written routine.
  747.  
  748.  
  749. Include:                stdlib.a
  750.  
  751.  
  752.  
  753. Routine:  PutCR
  754. ---------------
  755.  
  756. Category:             Character Output Routine 
  757.  
  758. Register on entry:    None
  759.  
  760. Register on return:   None
  761.  
  762. Flags affected:       None
  763.  
  764. Example of Usage:     PutCR
  765.  
  766.  
  767. Description:  Using PutCR is an easy way of printing a newline to the stdlib 
  768.               standard output. It prints a newline (carriage return/line feed) 
  769.               to the current standard output device.
  770.  
  771.  
  772. Include:                stdlib.a
  773.  
  774.  
  775. Routine: PutcStdOut
  776. -------------------
  777.  
  778. Category:              Character Output Routine
  779.  
  780. Registers on Entry:    AL- character to output
  781.  
  782. Registers on Return:   None
  783.  
  784. Flags Affected:        None
  785.  
  786. Example of Usage:
  787.                        mov AL, 'C'
  788.                        PutcStdOut        ; Writes "C" to standard output
  789.  
  790.  
  791. Description:  PutcStdOut calls DOS to print the character in AL to the standard
  792.               output device.  Although processing of non-ASCII characters and
  793.               control characters is undefined, most output devices handle these
  794.               characters properly.  In particular, most output devices properly
  795.               handle return, line feed, back space, and tab.  The output is
  796.               redirectable via DOS I/O redirection.
  797.  
  798.  
  799. Include:                stdlib.a
  800.  
  801.  
  802.  
  803. Routine: PutcBIOS
  804. -----------------
  805.  
  806. Category:              Character Output Routine
  807.  
  808. Registers on Entry:    AL- character to print
  809.  
  810. Registers on Return:   None
  811.  
  812. Flags Affected:        None
  813.  
  814. Example of Usage:
  815.                        mov AL, "C"
  816.                        PutcBIOS
  817.  
  818.  
  819. Description:  PutcBIOS prints the character in AL using the BIOS routines,
  820.               using INT 10H/AH=14 for teletype-like output.  Output through
  821.               this routine cannot be redirected; such output is always sent
  822.               to the video display on the PC (unless, of course, someone has
  823.               patched INT 10h).  Handles return, line feed, back space, and
  824.               tab.  Prints other control characters using the IBM Character
  825.           set.
  826.  
  827.  
  828. Include:         stdlib.a
  829.  
  830.  
  831.  
  832. Routine: GetOutAdrs
  833. -------------------
  834.  
  835. Category:             Character Output Routine
  836.  
  837. Registers on Entry:   None
  838.  
  839. Registers on Return:  ES:DI- address of current output routine (called by Putc)
  840.  
  841. Flags Affected:       None
  842.  
  843. Example of Usage: 
  844.                       GetOutAdrs
  845.                       mov word ptr SaveOutAdrs, DI
  846.                       mov word ptr SaveOutAdrs+2, ES
  847.  
  848. Description:  GetOutAdrs gets the address of the current output routine, perhaps
  849.               so you can save it or see if it is currently pointing at some
  850.               particular piece of code.  If you want to temporarily redirect
  851.               the output and then restore the original output routine, consider
  852.               using PushOutAdrs/PopOutAdrs described later.
  853.  
  854. Include:    stdlib.a
  855.  
  856.  
  857.  
  858.  
  859. Routine:  SetOutAdrs
  860. --------------------
  861.  
  862. Category:               Character Output Routine
  863.  
  864. Registers on Entry:     ES:DI - address of new output routine
  865.  
  866. Registers on return:    None 
  867.  
  868. Flags affected:         None
  869.  
  870. Example of Usage:
  871.  
  872.                         mov     es, seg NewOutputRoutine
  873.                         mov     di, offset NewOutputRoutine
  874.                         SetOutAdrs
  875.                         les     di, RoutinePtr
  876.                         SetOutAdrs
  877.  
  878. Description:  This routine redirects the stdlib standard output so that it
  879.               calls the routine who's address you pass in es:di.  This routine
  880.               expects the character to be in AL and must preserve all registers.
  881.               It handles the printable ASCII characters and the four control
  882.               characters return, line feed, back space, and tab.  (The routine
  883.               may be modified in the case that you wish to handle these codes
  884.               in a different fashion.)
  885.  
  886.  
  887. Include:        stdlib.a
  888.  
  889.  
  890. Routine:  PushOutAdrs
  891. ---------------------
  892.  
  893. Category:              Character Output Routine 
  894.  
  895. Registers on Entry:    ES:DI- Address of new output routine
  896.  
  897. Registers on Return:   None
  898.  
  899. Flags Affected:        Carry = 0 if operation is successful
  900.                        Carry = 1 if there were already 16 items on the stack
  901.  
  902. Example of Usage:  
  903.                        mov  ES, seg NewOutputRoutine
  904.                        mov  DI, offset NewOutputRoutine
  905.                        PushOutAdrs
  906.                           .
  907.                           .
  908.                           . 
  909.                        les  DI, RoutinePtr
  910.                        PushOutAdrs
  911.  
  912.  
  913. Description:  This routine "pushes" the current output address onto an internal
  914.               stack and then uses the value in es:di as the current output
  915.               routine address.  The PushOutAdrs and PopOutAdrs routines let you
  916.               easily save and redirect the standard output and then restore the
  917.               original output routine address later on.  If you attempt to push
  918.               more than 16 items on the stack, PushOutAdrs will ignore your
  919.               request and return with the carry flag set.  If PushOutAdrs is
  920.               successful, it will return with the carry flag clear.
  921.  
  922.  
  923. Include:          stdlib.a
  924.  
  925.  
  926.  
  927. Routine:  PopOutAdrs
  928. --------------------
  929.  
  930. Category:             Character Output Routine 
  931.  
  932. Registers on Entry:   None
  933.  
  934. Registers on Return:  ES:DI- Points at the previous stdout routine before
  935.                       the pop
  936.  
  937. Flags Affected:       None
  938.  
  939. Example of Usage:  
  940.                       mov ES, seg NewOutputRoutine
  941.                       mov DI, offset NewOutputRoutine
  942.                       PushOutAdrs
  943.                          .
  944.                          .
  945.                          .
  946.                       PopOutAdrs
  947.  
  948.  
  949. Description:  PopOutAdrs undoes the effects of PushOutAdrs.  It pops an item off
  950.               the internal stack and stores it into the output routine pointer.
  951.               The previous value in the output pointer is returned in es:di.
  952.               Defaults to PutcStdOut if you attempt to pop too many items off
  953.               the stack.
  954.  
  955. Include:    stdlib.a
  956.  
  957.  
  958.  
  959.  
  960. Routine:  Puts
  961. --------------
  962.  
  963. Category:            Character Output Routine 
  964.  
  965. Register on entry:   ES:DI register - contains the address of the string
  966.  
  967. Register on return:  None
  968.  
  969. Flags affected:      None
  970.  
  971. Example of Usage:
  972.                      les     di, StrToPrt
  973.                      puts
  974.                      putcr
  975.  
  976.  
  977. Description:   Puts prints a zero-terminated string whose address appears
  978.                in es:di.  Each character appearing in the string is printed
  979.                verbatim.  There are no special escape characters.  Unlike
  980.                the "C" routine by the same name, puts does not print a
  981.                newline after printing the string.  Use putcr if you want
  982.                to print the newline after printing a string with puts.
  983.  
  984.  
  985. Include:        stdlib.a
  986.  
  987.  
  988.  
  989. Routine:  Puth
  990. --------------
  991.  
  992. Category:             Character Output Routine
  993.  
  994. Register on entry:    AL 
  995.  
  996. Register on return:   AL
  997.  
  998. Flags affected:       None
  999.  
  1000. Example of Usage:
  1001.                       mov     al, 1fh
  1002.                       puth
  1003.  
  1004.  
  1005. Description:    The Puth routine Prints the value in the AL register as two
  1006.                 hexadecimal digits.  If the value in AL is between 0 and 0Fh, 
  1007.                 puth will print a leading zero.  This routine calls the stdlib
  1008.                 standard output routine (putc) to print all characters.
  1009.  
  1010.  
  1011. Include:        stdlib.a 
  1012.  
  1013.  
  1014.  
  1015. Routine:  Putw
  1016. --------------
  1017.  
  1018. Category:             Character Output Routine
  1019.  
  1020. Registers on Entry:   AX- Value to print
  1021.  
  1022. Registers on Return:  None
  1023.  
  1024. Flags Affected:       None
  1025.  
  1026. Example of Usage: 
  1027.                       mov AX, 0f1fh
  1028.                       putw
  1029.  
  1030.  
  1031. Description:  The Putw routine prints the value in the AX register as four
  1032.               hexadecimal digits (including leading zeros if necessary).  
  1033.               This routine calls the stdlib standard output routine (putc) 
  1034.               to print all characters.
  1035.  
  1036. Include:        stdlib.a
  1037.  
  1038.  
  1039.  
  1040. Routine:  Puti
  1041. --------------
  1042.  
  1043. Category:             Character Output Routine
  1044.  
  1045. Registers on Entry:   AX- Value to print
  1046.  
  1047. Registers on Return:  None
  1048.  
  1049. Flags Affected:       None
  1050.  
  1051. Example of Usage: 
  1052.                       mov AX, -1234
  1053.                       puti
  1054.  
  1055.  
  1056. Description:  Puti prints the value in the AX register as a decimal integer.
  1057.               This routine uses the exact number of screen positions required
  1058.               to print the number (including a position for the minus sign, if
  1059.               the number is negative).  This routine calls the stdlib standard
  1060.               output routine (putc) to print all characters.
  1061.  
  1062.  
  1063. Include:        stdlib.a
  1064.  
  1065.  
  1066.  
  1067. Routine:  Putu
  1068. --------------
  1069.  
  1070. Category:             Character Output Routine
  1071.  
  1072. Register on entry:    AX- Unsigned value to print.
  1073.  
  1074. Register on return:   None
  1075.  
  1076. Flags affected:       None
  1077.  
  1078. Example of Usage:
  1079.                       mov     ax, 1234
  1080.                       putu
  1081.  
  1082.  
  1083. Description:  Putu prints the value in the AX register as an unsigned integer.
  1084.               This routine uses the exact number of screen positions required
  1085.               to print the number.  This routine calls the stdlib standard
  1086.               output routine (putc) to print all characters.
  1087.  
  1088.  
  1089. Include:        stdlib.a
  1090.  
  1091.  
  1092.  
  1093.  
  1094. Routine:  Putl
  1095. --------------
  1096.  
  1097. Category:            Character Output Routine
  1098.  
  1099. Register on entry:   DX:AX- Value to print
  1100.  
  1101. Register on return:  None
  1102.  
  1103. Flags affected:      None
  1104.  
  1105. Example of Usage:
  1106.                      mov     dx, 0ffffh
  1107.                      mov     ax, -1234
  1108.                      putl
  1109.  
  1110.  
  1111. Description:   Putl prints the value in the DX:AX registers as an integer.
  1112.                This routine uses the exact number of screen positions
  1113.                required to print the number (including a position for the
  1114.                minus sign, if the number is negative).  This routine calls
  1115.                the stdlib standard output routine (putc) to print all
  1116.                characters.
  1117.  
  1118.  
  1119. Include:        stdlib.a
  1120.  
  1121.  
  1122.  
  1123. Routine:  Putul
  1124. ---------------
  1125.  
  1126. Category:             Character Output Routine
  1127.  
  1128. Register on entry:    DX:AX register
  1129.  
  1130. Register on return:   None
  1131.  
  1132. Flags affected:       None
  1133.  
  1134. Example of Usage:
  1135.                       mov     dx, 12h
  1136.                       mov     ax, 1234
  1137.                       putul
  1138.  
  1139.  
  1140. Description:    Putul prints the value in the DX:AX registers as an unsigned
  1141.                 integer.  This routine uses the exact number of screen
  1142.                 positions required to print the number.  This routine calls 
  1143.         the stdlib standard output routine (putc) to print all
  1144.         characters.
  1145.  
  1146.  
  1147. Include:        stdlib.a
  1148.  
  1149.  
  1150. Routine:  PutISize
  1151. ------------------
  1152.  
  1153. Category:              Character Output Routine
  1154.  
  1155. Registers on Entry:    AX - Integer value to print
  1156.                        CX - Minimum number of print positions to use
  1157.  
  1158. Registers on return:   None 
  1159.  
  1160. Flags affected:
  1161.  
  1162. Example of Usage:
  1163.                        mov     cx, 5
  1164.                        mov     ax, I
  1165.                        PutISize
  1166.                            .
  1167.                            . 
  1168.                            .
  1169.                        mov     cx, 12
  1170.                        mov     ax, J
  1171.                        PutISize
  1172.  
  1173.  
  1174. Description:    PutISize prints the signed integer value in AX to the
  1175.                 stdlib standard output device using a minimum of n print
  1176.                 positions.  CX contains n, the minimum field width for the
  1177.                 output value.  The number (including any necessary minus sign)
  1178.                 is printed right justified in the output field.
  1179.                 If the number in AX requires more print positions than
  1180.                 specified by CX, PutISize uses however many print positions
  1181.                 are necessary to actually print the number.  If you specify
  1182.                 zero in CX, PutISize uses the minimum number of print positions
  1183.                 required.  Of course, PutI will also use the minimum number
  1184.                 of print positions without disturbing the value in the CX
  1185.                 register.
  1186.  
  1187.                 Note that, under no circumstances, will the number in AX
  1188.                 ever require more than 6 print positions (-32,767 requires
  1189.                 the most print positions).
  1190.  
  1191.  
  1192. Include:        stdlib.a
  1193.  
  1194.  
  1195.  
  1196. Routine:  PutUSize
  1197. ------------------
  1198.  
  1199. Category:              Character Output Routine
  1200.  
  1201. Registers on entry:    AX- Value to print
  1202.                CX- Minimum field width
  1203.  
  1204. Registers on return:   None
  1205.  
  1206. Flags affected:        None
  1207.  
  1208. Example of usage: 
  1209.                        mov     cx, 8
  1210.                        mov     ax, U
  1211.                        PutUSize
  1212.  
  1213.  
  1214. Description:  PutUSize prints the value in AX as an unsigned decimal integer.
  1215.               The minimum field width specified by the value in CX.
  1216.               Like PutISize above except this one prints unsigned values.  
  1217.               Note that the maximum number of print positions required by any 
  1218.               number (e.g., 65,535) is five.
  1219.  
  1220.  
  1221. Include:        stdlib.a
  1222.  
  1223.  
  1224.  
  1225. Routine:  PutLSize
  1226. ------------------
  1227.  
  1228. Category:            Character Output Routine
  1229.  
  1230. Register on entry:   DX:AX-32 bit value to print
  1231.              CX- Minimum field width
  1232.  
  1233. Register on return:  None
  1234.  
  1235. Flags affected:      None
  1236.  
  1237. Example of Usage:
  1238.                      mov     cx, 16
  1239.                      mov     dx, word ptr L+2
  1240.                      mov     ax, word ptr L
  1241.                      PutLSize
  1242.  
  1243.  
  1244. Description:   PutLSize is similar to PutISize, except this prints the long 
  1245.                integer value in DX:AX.  Note that there may be as many as 
  1246.                11 print positions (e.g., -1,000,000,000).
  1247.  
  1248. Include:        stdlib.a
  1249.  
  1250.  
  1251.  
  1252.  
  1253. Routine:  PutULSize
  1254. -------------------
  1255.  
  1256.  
  1257. Category:            Character Output Routine
  1258.  
  1259.  
  1260. Register on entry:   AX : DX and CX
  1261.  
  1262.  
  1263. Register on return:  None
  1264.  
  1265.  
  1266. Flags affected:      None
  1267.  
  1268.  
  1269. Example of usage:    mov     cx, 8
  1270.                      mov     dx, word ptr UL+2
  1271.                      mov     ax, word ptr UL
  1272.                      PutULSize
  1273.  
  1274.  
  1275. Description:  Prints the value in DX:AX as a long unsigned decimal integer.
  1276.               Prints the number in a minimum field width specified by the
  1277.               value in CX.  Just like PutLSize above except this one prints
  1278.               unsigned numbers rather than signed long integers.  The largest
  1279.               field width for such a value is 10 print positions.
  1280.  
  1281.  
  1282. Include:        stdlib.a
  1283.  
  1284.  
  1285. Routine:   Print
  1286. ----------------
  1287.  
  1288. Category:             Character Output Routine
  1289.  
  1290. Register on entry:    CS:RET - Return address points at the string to print.
  1291.  
  1292. Register on return:   None
  1293.  
  1294. Flags affected:       None
  1295.  
  1296. Examples of Usage:    print
  1297.                       db      "Print this string to the display device"
  1298.                       db      13,10
  1299.                       db      "This appears on a new line"
  1300.                       db      13,10
  1301.                       db      0
  1302.  
  1303.  
  1304. Description:   Print lets you print string literals in a convenient
  1305.                fashion.  The string to print immediately follows the call
  1306.                to the print routine.  The string must contain a
  1307.                zero terminating byte and may not contain any intervening
  1308.                zero bytes.  Since the print routine returns to the address
  1309.                immediately following the zero terminating byte, forgetting
  1310.                this byte or attempting to print a zero byte in the middle
  1311.                of a literal string will cause print to return to an
  1312.                unexpected instruction.  This usually hangs up the machine.
  1313.                Be very careful when using this routine!
  1314.  
  1315.  
  1316. Include:        stdlib.a
  1317.  
  1318.  
  1319. Routine:        Printf
  1320. ----------------------
  1321.  
  1322. Category:             Character Output Routine
  1323.  
  1324. Register on entry:    CS:RET - Return address points at the format string
  1325.  
  1326. Register on return:   None
  1327.  
  1328. Flags affected:       None
  1329.  
  1330. Example of Usage:
  1331.                       printf
  1332.                       db      "Indirect access to i: %^d",13,10,0
  1333.                       dd      IPtr;
  1334.                       printf
  1335.                       db      "A string allocated on the heap: %-\.32^s"
  1336.                       db      13,10,0
  1337.                       dd      SPtr
  1338.  
  1339.  
  1340.  
  1341. Descriptions:   Printf, like its "C" namesake, provides formatted output
  1342.                 capabilities for the stdlib package.  A typical call to printf
  1343.                 always takes the following form:
  1344.  
  1345.                         printf
  1346.                         db              "format string",0
  1347.                         dd              operand1, operand2, ..., operandn
  1348.  
  1349.                 The format string is comparable to the one provided in the
  1350.                 "C" programming language.  For most characters, printf simply
  1351.                 prints the characters in the format string up to the
  1352.                 terminating zero byte.  The two exceptions are characters
  1353.                 prefixed by a backslash ("\") and characters prefixed by a
  1354.                 percent sign ("%").  Like C's printf, stdlib's printf uses
  1355.                 the backslash as an escape character and the percent sign as
  1356.                 a lead-in to a format string.
  1357.  
  1358.                 Printf uses the escape character ("\") to print special
  1359.                 characters in a fashion similar to, but not identical to C's
  1360.                 printf.  Stdlib's printf routine supports the following
  1361.                 special characters:
  1362.  
  1363.                 *  r     Print a carriage return (but no line feed)
  1364.                 *  n     Print a new line character (carriage return/line feed).
  1365.                 *  b     Print a backspace character.
  1366.                 *  t     Print a tab character.
  1367.                 *  l     Print a line feed character (but no carriage return).
  1368.                 *  f     Print a form feed character.
  1369.                 *  \     Print the backslash character.
  1370.                 *  %     Print the percent sign character.
  1371.                 *  0xhh  Print ASCII code hh, represented by two hex digits.
  1372.  
  1373.                 C users should note a couple of differences between stdlib's
  1374.                 escape sequences and C's.  First, use "\%" to print a percent
  1375.                 sign within a format string, not "%%".  C doesn't allow the
  1376.                 use of "\%" because the C compiler processes "\%" at compile
  1377.                 time (leaving a single "%" in the object code) whereas printf
  1378.                 processes the format string at run-time.  It would see a single
  1379.                 "%" and treat it as a format lead-in character.  Stdlib's
  1380.                 printf, on the other hand, processes both the "\" and "%" and
  1381.                 run-time, therefore it can distinguish "\%".
  1382.  
  1383.                 Strings of the form "\0xhh" must contain exactly two hex
  1384.                 digits.  The current printf routine isn't robust enough to
  1385.                 handle sequences of the form "\0xh" which contain only a
  1386.                 single hex digit.  Keep this in mind if you find printf
  1387.                 chopping off characters after you print a value.
  1388.  
  1389.                 There is absolutely no reason to use any escape character
  1390.                 sequences except "\0x00".  Printf grabs all characters
  1391.                 following the call to printf up to the terminating zero byte
  1392.                 (which is why you'd need to use "\0x00" if you want to print
  1393.                 the null character, printf will not print such values).
  1394.                 Stdlib's printf routine doesn't care how those characters got
  1395.                 there.  In particular, you are not limited to using a single
  1396.                 string after the printf call.  The following is perfectly
  1397.         legal:
  1398.  
  1399.  
  1400.                 printf
  1401.                 db      "This is a string",13,10
  1402.                 db      "This is on a new line",13,10
  1403.                 db      "Print a backspace at the end of this line:"
  1404.                 db      8,13,10,0
  1405.  
  1406.  
  1407.                 Your code will run a tiny amount faster if you avoid the use
  1408.                 of the escape character sequences.  More importantly, the
  1409.                 escape character sequences take at least two bytes.  You can
  1410.                 encode most of them as a single byte by simply embedding the
  1411.                 ASCII code for that byte directly into the code stream.
  1412.                 Don't forget, you cannot embed a zero byte into the code
  1413.                 stream.  A zero byte terminates the format string.  Instead,
  1414.                 use the "\0x00" escape sequence.
  1415.  
  1416.                 Format sequences always between with "%".  For each format
  1417.                 sequence you must provide a far pointer to the associated
  1418.                 data immediately following the format string, e.g.,
  1419.  
  1420.                     printf
  1421.                     db      "%i %i",0
  1422.                     dd      i,j
  1423.  
  1424.                 Format sequences take the general form "%s\cn^f" where:
  1425.  
  1426.                 *       "%" is always the "%" character.  Use "\%" if you
  1427.                         actually want to print a percent sign.
  1428.                 *       s is either nothing or a minus sign ("-").
  1429.                 *       "\c" is also optional, it may or may not appear in
  1430.                         the format item.  "c" represents any printable
  1431.                         character.
  1432.                 *       "n" represents a string of 1 or more decimal digits.
  1433.                 *       "^" is just the caret (up-arrow) character.
  1434.                 *       "f" represents one of the format characters: i, d, x,
  1435.                         h, u, c, s, ld, li, lx, or lu.
  1436.  
  1437.                 The "s", "\c", "n", and "^" items are optional, the "%" and
  1438.                 "f" items must be present.  Furthermore, the order of these
  1439.                 items in the format item is very important.  The "\c" entry,
  1440.                 for example, cannot precede the "s" entry.  Likewise, the "^"
  1441.                 character, if present, must follow everything except the "f"
  1442.                 character(s).
  1443.  
  1444.                 The format characters i, d, x, h, u, c, s, ld, li, lx, and
  1445.                 lu control the output format for the data.  The i and d
  1446.                 format characters perform identical functions, they tell
  1447.                 printf to print the following value as a 16-bit signed
  1448.                 decimal integer.  The x and h format characters instruct
  1449.                 printf to print the specified value as a 16-bit or 8-bit
  1450.                 hexadecimal value (respectively).  If you specify u, printf
  1451.                 prints the value as a 16-bit unsigned decimal integer.
  1452.                 Using c tells printf to print the value as a single character.
  1453.                 S tells printf that you're supplying the address of a
  1454.                 zero-terminated character string, printf prints that string.
  1455.                 The ld, li, lx, and lu entries are long (32-bit) versions of
  1456.                 d/i, x, and u.  The corresponding address points at a 32-bit
  1457.                 value which printf will format and print to the standard output.
  1458.                 The following example demonstrates these format items:
  1459.  
  1460.                 printf
  1461.                 db      "I= %i, U= %u, HexC= %h, HexI= %x, C= %c, "
  1462.                 db      "S= %s",13,10
  1463.                 db      "L= %ld",13,10,0
  1464.                 dd      i,u,c,i,c,s,l
  1465.  
  1466.                 The number of far addresses (specified by operands to the "dd"
  1467.                 pseudo-opcode) must match the number of "%" format items in
  1468.                 the format string.  Printf counts the number of "%" format
  1469.                 items in the format string and skips over this many far
  1470.                 addresses following the format string.  If the number of
  1471.                 items do not match, the return address for printf will be
  1472.                 incorrect and the program will probably hang or otherwise
  1473.                 malfunction.  Likewise (as for the print routine), the format
  1474.                 string must end with a zero byte.  The addresses of the items
  1475.                 following the format string must point directly at the memory
  1476.                 locations where the specified data lies.
  1477.  
  1478.                 When used in the format above, printf always prints the
  1479.                 values using the minimum number of print positions for each
  1480.                 operand.  If you want to specify a minimum field width, you
  1481.                 can do so using the "n" format option.  A format item of the
  1482.                 format "%10d" prints a decimal integer using at least ten
  1483.                 print positions.  Likewise, "%16s" prints a string using at
  1484.                 least 16 print positions.  If the value to print requires
  1485.                 more than the specified number of print positions, printf
  1486.                 will use however many are necessary.  If the value to print
  1487.                 requires fewer, printf will always print the specified number,
  1488.                 padding the value with blanks.  Printf will print the value
  1489.                 right justified in the print field (regardless of the data's
  1490.                 type).  If you want to print the value left justified in the
  1491.                 output file, use the "-" format character as a prefix to the
  1492.                 field width, e.g.,
  1493.  
  1494.                 printf
  1495.                 db      "%-17s",0
  1496.                 dd      string
  1497.  
  1498.                 In this example, printf prints the string using a 17 character
  1499.                 long field with the string left justified in the output field.
  1500.                 By default, printf blank fills the output field if the value
  1501.                 to print requires fewer print positions than specified by the
  1502.                 format item.  The "\c" format item allows you to change the
  1503.                 padding character.  For example, to print a value, right
  1504.                 justified, using "*" as the padding character you would use
  1505.                 the format item "%\*10d".  To print it left justified you
  1506.                 would use the format item "%-\*10d".  Note that the "-" must
  1507.                 precede the "\*".  This is a limitation of the current
  1508.                 version of the software.  The operands must appear in this
  1509.                 order.  Normally, the address(es) following the printf
  1510.                 format string must be far pointers to the actual data to print.
  1511.                 On occasion, especially when allocating storage on the heap
  1512.                 (using malloc), you may not know (at assembly time) the
  1513.                 address of the object you want to print.  You may have only
  1514.                 a pointer to the data you want to print.  The "^" format
  1515.                 option tells printf that the far pointer following the format
  1516.                 string is the address of a pointer to the data rather than
  1517.                 the address of the data itself.  This option lets you access
  1518.                 the data indirectly.
  1519.  
  1520.                 Note: unlike C, stdlib's printf routine does not support
  1521.                 floating point output.  Putting floating point into printf
  1522.         would increase the size of this routine a tremendous amount.
  1523.         Since most people don't need the floating point output
  1524.         facilities, it doesn't appear here.  Check out PRINTFF.
  1525.  
  1526. Include:        stdlib.a
  1527.  
  1528.  
  1529.  
  1530. Routine:  PRINTFF
  1531. -----------------
  1532.  
  1533.  
  1534. Category:             Character Output Routine
  1535.  
  1536. Registers on Entry:   CS:RET- Points at format string and other parameters.
  1537.  
  1538. Registers on Return:  If your program prints floating point values, this
  1539.               routine modifies the floating point accumulator and
  1540.               floating point operand "pseudo-registers" in the
  1541.               floating point package.
  1542.  
  1543. Flags Affected:       None
  1544.  
  1545. Examples of Usage:
  1546.             printff
  1547.             db    "I = %d, R = %7.2f  F = 12.5e  G = 9.2gf\n",0
  1548.             dd    i, r, f, g
  1549.  
  1550. Description:  
  1551.         This code works just like printf except it also allows the
  1552.         output of floating point values.  The output formats are 
  1553.         the following:
  1554.  
  1555.         Single Precision:
  1556.  
  1557.          mm.nnF-    Prints a field width of mm chars with nn digits
  1558.                 appearing after the decimal point.
  1559.  
  1560.          nnE-        Prints a floating point value using scientific
  1561.                 notation in a field width of nn chars.
  1562.  
  1563.         Double Precision:
  1564.  
  1565.          mm.nnGF-    As above, for double precision values.
  1566.          nnGE-        As above, for double precision values.
  1567.  
  1568.         Extended Precision-
  1569.  
  1570.          mm.nnLF-    As above, for extended precision values.
  1571.          nnLE-        As above, for extended precision values.
  1572.  
  1573.  
  1574.         Since PRINTFF supports everything PRINTF does, you should not
  1575.         use both routines in the same program (just use PRINTF).  The
  1576.         PRINTF & PRINTFF macros check for this and will print a warning
  1577.         message if you've included both routines.  Using both will not
  1578.         cause your program to fail, but it will make your program
  1579.         unnecessarily larger.  You should not use PRINTFF unless you
  1580.         really need to print floating point values.  When you use
  1581.         PRINTFF, it forces the linker to load in the entire floating
  1582.         point package, making your program considerably larger.
  1583.  
  1584. Include:                  stdlib.a
  1585.  
  1586.  
  1587.  
  1588. Conversion Routines
  1589. -------------------
  1590.  
  1591.  
  1592. The stdlib conversion routines follow a uniform format of storing the data
  1593. to be converted and returned.  Most routines accept input and return data
  1594. of either an ASCII string of characters, stored in the ES:DI register, or
  1595. integers, stored in the DX:AX register.  If a value is just a 16 or 8-bit
  1596. value then it will be stored in AX or AL.
  1597.  
  1598. Since there is a possibility of an error in the input values to be converted,
  1599. such as it does not contain a proper value to convert, we use the
  1600. carry flag to show error status.  If the error flag is set then an error has
  1601. occured and things are okay if the carry flag is clear.
  1602.  
  1603.  
  1604.  
  1605.  
  1606.  
  1607. Routine:  ATOL (2)
  1608. ------------------
  1609.  
  1610.  
  1611. Category:             Conversion Routine
  1612.  
  1613. Registers on Entry:   ES:DI- Points at string to convert
  1614.  
  1615. Registers on Return:  DX:AX- Long integer converted from string
  1616.               ES:DI- Points at first non-digit (ATOL2 only)
  1617.  
  1618. Flags Affected:       Carry flag- Error status
  1619.  
  1620. Examples of Usage:
  1621.               gets         ;Get a string from user
  1622.               ATOL         ;Convert to a value in DX:AX
  1623.  
  1624.  
  1625. Description:  ATOL converts the string of digits that ES:DI points at to a
  1626.           long (signed) integer value and returns this value in DX:AX.
  1627.           Note that the routine stops on the first non-digit.
  1628.           If the string does not begin with a digit, this routine returns
  1629.           zero.  The only exception to the "string of digits" only rule is
  1630.           that the number can have a preceding minus sign to denote a
  1631.           negative number.  Note that this routine does not allow leading
  1632.           spaces.  ATOL2 works in a similar fashion except it doesn't
  1633.           preserve the DI register.  That is, ATOL2 leaves DI pointing at
  1634.           the first character beyond the string of digits.  ATOL/ATOL2 both
  1635.           return the carry flag clear if it  translated the string of
  1636.           digits without error.  It returns the carry flag set if overflow
  1637.           occurred.
  1638.  
  1639.  
  1640. Include:                  stdlib.a
  1641.  
  1642.  
  1643.  
  1644. Routine:  AtoUL (2)
  1645. -------------------
  1646.  
  1647. Category:            Conversion Routine
  1648.  
  1649. Register on entry:   ES:DI- address of the string to be converted
  1650.  
  1651. Register on return:  DX:AX- 32-bit unsigned integer
  1652.              ES:DI- Points at first character beyond digits (ATOUL2
  1653.                 only)
  1654.  
  1655. Flags affected:      Carry flag- Set if error, clear if okay.
  1656.  
  1657. Examples of Usage:
  1658.              les InputString
  1659.              AtoUL
  1660.  
  1661.  
  1662. Description:  AtoUL converts the string pointed by ES:DI to a 32-bit unsigned
  1663.           integer.  It places the 32-bit unsigned integer into the memory
  1664.           address pointed by DX:AX. If there is an error in conversion,
  1665.           the carry flag will set to one. If there is not an error, the
  1666.           carry flag will be set to zero.
  1667.  
  1668.           ATOUL2 does not preserve DI.  It returns with DI pointing at
  1669.           the first non-digit character in the string.
  1670.  
  1671. Include:        stdlib.a
  1672.  
  1673.  
  1674.  
  1675. Routine:    ATOU (2)
  1676. --------------------
  1677.  
  1678. Category:            Conversion Routine
  1679.  
  1680. Register on entry:   ES:DI points at string to convert
  1681.  
  1682. Register on return:  AX-    unsigned 16-bit integer
  1683.              ES:DI- points at first non-digit (ATOU2 only)
  1684.  
  1685. Flags affected:      carry flag - error status
  1686.  
  1687. Example of Usage:
  1688.  
  1689. Description:    ATOU converts an ASCII string of digits, pointed to by ES:DI,
  1690.         to unsigned integer format. It places the unsigned 16-bit
  1691.         integer, converted from the string, into the AX register.
  1692.         ATOI works the same, except it handle unsigned 16-bit integers
  1693.         in the range 0..65535.
  1694.  
  1695.         ATOU2 leaves DI pointing at the first non-digit in the string.
  1696.  
  1697. Include:        stdlib.a
  1698.  
  1699.  
  1700.  
  1701. Routine: ATOH (2)
  1702. -----------------
  1703.  
  1704. Category:             Conversion Routine
  1705.  
  1706. Registers on Entry:   ES:DI- Points to string to convert
  1707.  
  1708. Registers on Return:  AX- Unsigned 16-bit integer converted from hex string
  1709.               DI (ATOH2)- First character beyond string of hex digits
  1710.  
  1711. Flags Affected:       Carry = Error status
  1712.  
  1713. Example of Usage:
  1714.               les  DI, Str2Convrt
  1715.               atoh                  ;Convert to value in AX.
  1716.               putw                  ;Print word in AX.
  1717.  
  1718.  
  1719. Description:  ATOH converts a string of hexadecimal digits, pointed to by
  1720.           ES:DI, into unsigned 16-bit numeric form. It returns the value in
  1721.           the AX register.  If there is an error in conversion, the carry
  1722.           flag will set to one.  If there is not an error, the carry flag
  1723.           will be clear.  ATOH2 works the same except it leaves DI
  1724.           pointing at the first character beyond the string of hex digits.
  1725.  
  1726. Include:        stdlib.a
  1727.  
  1728.  
  1729. Routine: ATOLH (2)
  1730. ------------------
  1731.  
  1732. Category:             Conversion Routine
  1733.  
  1734. Registers on Entry:   ES:DI- Points to string to convert
  1735.  
  1736. Registers on Return:  DX:AX- Unsigned 32-bit integer converted from hex string
  1737.               DI (ATOLH2)- First character beyond string of hex digits
  1738.  
  1739. Flags Affected:       Carry = Error status
  1740.  
  1741. Example of Usage:
  1742.               les  DI, Str2Convrt
  1743.               atolh                 ;Convert to value in DX:AX
  1744.  
  1745. Description:  ATOLH converts a string of hexadecimal digits, pointed to by
  1746.           ES:DI, into unsigned 32-bit numeric form. It returns the value in
  1747.           the DX:AX register.  If there is an error in conversion, the carry
  1748.           flag will set to one.  If there is not an error, the carry flag
  1749.           will be clear.  ATOLH2 works the same except it leaves the DI
  1750.           register pointing at the first non-hex digit.
  1751.  
  1752.  
  1753. Include:        stdlib.a
  1754.  
  1755.  
  1756.  
  1757. Routine:   ATOI (2)
  1758. -------------------
  1759.  
  1760. Category:             Conversion Routine
  1761.  
  1762. Register on entry:    ES:DI- Points at string to convert.
  1763.  
  1764. Register on return:   AX- Integer converted from string.
  1765.               DI (ATOI2)- First character beyond string of digits.
  1766.  
  1767. Flags affected:       Error status
  1768.  
  1769. Examples of Usage:
  1770.               les  DI, Str2Convrt
  1771.               atoi                 ;Convert to value in AX
  1772.  
  1773.  
  1774. Description:   Works just like ATOL except it translates the string to a
  1775.            signed 16-bit integer rather than a 32-bit long integer.
  1776.  
  1777.  
  1778. Include:              stdlib.a
  1779.  
  1780.  
  1781. Routine ITOA (2,M)
  1782. ------------------
  1783.  
  1784. Category:             Conversion Routine
  1785.  
  1786. Registers on Entry:   AX- Signed 16-bit value to convert to a string
  1787.               ES:DI- Pointer to buffer to hold result (ITOA/ITOA2
  1788.                  only).
  1789.  
  1790. Registers on Return:  ES:DI- Pointer to string containing converted
  1791.               characters (ITOA/ITOAM only).
  1792.               ES:DI- Pointer to zero-terminating byte of converted
  1793.                  string (ITOA2 only).
  1794.  
  1795. Flags Affected:       Carry flag is set on memory allocation error (ITOAM only)
  1796.  
  1797. Examples of Usage:
  1798.               mov     ax, -1234
  1799.               ITOAM                   ;Convert to string.
  1800.               puts                    ;Print it.
  1801.               free                    ;Deallocate string.
  1802.  
  1803.               mov     di, seg buffer
  1804.               mov     es, di
  1805.               lea     di, buffer
  1806.               mov     ax, -1234
  1807.               ITOA              ;Leaves string in BUFFER.
  1808.  
  1809.               mov     di, seg buffer
  1810.               mov     es, di
  1811.               lea     di, buffer
  1812.               mov     ax, -1234
  1813.               ITOA2              ;Leaves string in BUFFER and
  1814.                           ;ES:DI pointing at end of string.
  1815.  
  1816.  
  1817. Description:    These routines convert an integer value to a string of
  1818.         characters which represent that integer.  AX contains the
  1819.         signed integer you wish to convert.
  1820.  
  1821.         ITOAM automatically allocates storage on the heap for the
  1822.         resulting string, you do not have to pre-allocate this
  1823.         storage.  ITOAM returns a pointer to the (zero-terminated)
  1824.         string in the ES:DI registers.  It ignores the values in
  1825.         ES:DI on input.
  1826.  
  1827.         ITOA requires that the caller allocate the storage for the
  1828.         string (maximum you will need is seven bytes) and pass a
  1829.         pointer to this buffer in ES:DI.  ITOA returns with ES:DI
  1830.         pointing at the beginning of the converted string.
  1831.  
  1832.         ITOA2 also requires that you pass in the address of a buffer
  1833.         in the ES:DI register pair.  However, it returns with ES:DI
  1834.         pointing at the zero-terminating byte of the string.  This
  1835.         lets you easily build up longer strings via multiple calls
  1836.         to routines like ITOA2.
  1837.  
  1838. Include:        stdlib.a
  1839.  
  1840.  
  1841.  
  1842. Routine:   UTOA (2,M)
  1843. ---------------------
  1844.  
  1845. Category:            Conversion Routine
  1846.  
  1847. Registers on entry:   AX - unsigned 16-bit integer to convert to a string
  1848.               ES:DI- Pointer to buffer to hold result (UTOA/UTOA2
  1849.                  only).
  1850.  
  1851. Registers on Return:  ES:DI- Pointer to string containing converted
  1852.               characters (UTOA/UTOAM only).
  1853.               ES:DI- Pointer to zero-terminating byte of converted
  1854.                  string (UTOA2 only).
  1855.  
  1856. Flags affected:       Carry set denotes malloc error (UTOAM only)
  1857.  
  1858. Example of Usage:
  1859.               mov     ax, 65000
  1860.               utoa
  1861.               puts
  1862.               free
  1863.  
  1864.               mov     di, seg buffer
  1865.               mov     es, di
  1866.               lea     di, buffer
  1867.               mov     ax, -1234
  1868.               ITOA              ;Leaves string in BUFFER.
  1869.  
  1870.               mov     di, seg buffer
  1871.               mov     es, di
  1872.               lea     di, buffer
  1873.               mov     ax, -1234
  1874.               ITOA2              ;Leaves string in BUFFER and
  1875.                           ;ES:DI pointing at end of string.
  1876.  
  1877.  
  1878. Description:    UTOAx converts a 16-bit unsigned integer value in AX to a
  1879.         string of characters which represents that value.  UTOA,
  1880.         UTOA2, and UTOAM behave in a manner analogous to ITOAx.  See
  1881.         the description of those routines for more details.
  1882.  
  1883.  
  1884. Include:       stdlib.a
  1885.  
  1886.  
  1887.  
  1888. Routine:   HTOA (2,M)
  1889. ---------------------
  1890.  
  1891. Category:            Conversion Routine
  1892.  
  1893. Registers on entry:   AL - 8-bit integer to convert to a string
  1894.               ES:DI- Pointer to buffer to hold result (HTOA/HTOA2
  1895.                  only).
  1896.  
  1897. Registers on Return:  ES:DI- Pointer to string containing converted
  1898.               characters (HTOA/HTOAM only).
  1899.               ES:DI- Pointer to zero-terminating byte of converted
  1900.                  string (HTOA2 only).
  1901.  
  1902. Flags affected:      Carry set denotes memory allocation error (HTOAM only)
  1903.  
  1904.  
  1905. Description:    The HTOAx routines convert an 8-bit value in AL to the two-
  1906.         character hexadecimal representation of that byte.  Other
  1907.         that that, they behave just like ITOAx/UTOAx.  Note that
  1908.         the resulting buffer must have at least three bytes for
  1909.         HTOA/HTOA2.
  1910.  
  1911.  
  1912. Include:        stdlib.a
  1913.  
  1914.  
  1915. Routine:  WTOA (2,M)
  1916. --------------------
  1917.  
  1918. Category:             Conversion Routine
  1919.  
  1920. Registers on Entry:   AX- 16-bit value to convert to a string
  1921.               ES:DI- Pointer to buffer to hold result (WTOA/WTOA2
  1922.                  only).
  1923.  
  1924. Registers on Return:  ES:DI- Pointer to string containing converted
  1925.               characters (WTOA/WTOAM only).
  1926.               ES:DI- Pointer to zero-terminating byte of converted
  1927.                  string (WTOA2 only).
  1928.  
  1929. Flags Affected:       Carry set denotes memory allocation error (WTOAM only)
  1930.  
  1931. Example of Usage:
  1932.               Like WTOA above
  1933.  
  1934.  
  1935. Description:  WTOAx converts the 16-bit value in AX to a string of four
  1936.           hexadecimal digits. It behaves exactly like HTOAx except
  1937.           it outputs four characters (and requires a five byte buffer).
  1938.  
  1939.  
  1940. Include:        stdlib.a
  1941.  
  1942.  
  1943.  
  1944. Routine:  LTOA (2,M)
  1945. --------------------
  1946.  
  1947. Category:             Conversion Routine
  1948.  
  1949. Registers on entry:   DX:AX (contains a signed 32 bit integer)
  1950.               ES:DI- Pointer to buffer to hold result (LTOA/LTOA2
  1951.                  only).
  1952.  
  1953. Registers on Return:  ES:DI- Pointer to string containing converted
  1954.               characters (LTOA/LTOAM only).
  1955.               ES:DI- Pointer to zero-terminating byte of converted
  1956.                  string (LTOA2 only).
  1957.  
  1958. Flags affected:       Carry set if memory allocation error (LTOAM only)
  1959.  
  1960.  
  1961. Example of Usage: 
  1962.             mov    di, seg buffer    ;Get address of storage
  1963.             mov    es, di        ; buffer.
  1964.             lea    di, buffer
  1965.             mov    ax, word ptr value
  1966.             mov    dx, word ptr value+2
  1967.             ltoa
  1968.  
  1969. Description:    LtoA converts the 32-bit signed integer in DX:AX to a string
  1970.         of characters.  LTOA stores the string at the address specified
  1971.         in ES:DI (there must be at least twelve bytes available at
  1972.         this address) and returns with ES:DI pointing at this buffer.
  1973.         LTOA2 works the same way, except it returns with ES:DI
  1974.         pointing at the zero terminating byte.  LTOAM allocates
  1975.         storage for the string on the heap and returns a pointer
  1976.         to the string in ES:DI.
  1977.  
  1978. Include:        stdlib.a
  1979.  
  1980.  
  1981.  
  1982. Routine:  ULTOA (2,M)
  1983. ---------------------
  1984.  
  1985. Category:             Conversion Routine
  1986.  
  1987. Registers on Entry:   DX:AX- Unsigned 32-bit value to convert to a string
  1988.               ES:DI- Pointer to buffer to hold result (LTOA/LTOA2
  1989.                  only).
  1990. Registers on Return:  ES:DI- Pointer to string containing converted
  1991.               characters (LTOA/LTOAM only).
  1992.               ES:DI- Pointer to zero-terminating byte of converted
  1993.                  string (LTOA2 only).
  1994.  
  1995. Flags Affected:       Carry is set if malloc error (ULTOAM only)
  1996.  
  1997. Example of Usage:  
  1998.                       Like LTOA
  1999.  
  2000.  
  2001. Description:  Like LTOA except this routine handles unsigned integer values.
  2002.  
  2003. Include:    stdlib.a
  2004.  
  2005.  
  2006.  
  2007. Routine:  SPrintf (2,M)
  2008. -----------------------
  2009.  
  2010. Category:            Conversion Routine
  2011.              In-Memory Formatting Routine
  2012.  
  2013. Registers on entry:  CS:RET - Pointer to format string and operands of the
  2014.                   sprintf routine
  2015.              ES:DI-   Address of buffer to hold output string
  2016.                   (sprintf/sprintf2 only)
  2017.  
  2018. Register on return:  ES:DI register - pointer to a string containing
  2019.                       output data (sprintf/sprintfm only).
  2020.                       Pointer to zero-terminating byte at the
  2021.                       end of the converted string (sprintf2
  2022.                       only).
  2023.  
  2024. Flags affected:      Carry is set if memory allocation error (sprintfm only).
  2025.  
  2026. Example of Usage:
  2027.              sprintfm
  2028.              db      "I=%i, U=%u, S=%s",13,10,0
  2029.              db      i,u,s
  2030.              puts
  2031.              free
  2032.  
  2033.  
  2034. Description:   SPrintf is an in-memory formatting routine. It is similar to
  2035.            C's sprintf routine.
  2036.  
  2037.            The programmer selects the maximum length of the output string.
  2038.            SPrintf works in a manner quite similar to printf, except sprintf
  2039.            writes its output to a string variable rather than to the stdlib
  2040.            standard output.
  2041.  
  2042.            SPrintfm, by default, allocates 2048 characters for the string
  2043.            and then deallocates any unnecessary storage.  An external
  2044.            variable, sp_MaxBuf, holds the number of bytes to allocate upon
  2045.            entry into sprintfm.  If you wish to allocate more or less than
  2046.            2048 bytes when calling sprintf, simply change the value of this
  2047.            public variable (type is word).  Sprintfm calls malloc to
  2048.            allocate the storage dynamically.  You should call free to
  2049.            return this buffer to the heap when you are through with it.
  2050.  
  2051.            Sprintf and Sprintf2 expect you to pass the address of a buffer
  2052.            to them.  You are responsible for supplying a sufficiently
  2053.            sized buffer to hold the result.
  2054.  
  2055. Include:             stdlib.a
  2056.  
  2057.  
  2058.  
  2059. Routine:  SScanf
  2060. ----------------
  2061.  
  2062. Category:              Conversion Routine
  2063.                Formatted In-Memory Conversion Routine
  2064.  
  2065. Registers on Entry:    ES:DI - points at string containing values to convert
  2066.  
  2067. Registers on return:   None
  2068.  
  2069. Flags affected:           None
  2070.  
  2071. Example of Usage:
  2072.  
  2073.           ; this code reads the values for i, j, and s from the characters
  2074.           ; starting at memory location Buffer.
  2075.  
  2076.                les   di, Buffer
  2077.                SScanf
  2078.                db    "%i %i %s",0
  2079.                dd     i, j, s
  2080.  
  2081.  
  2082. Description:  SScanf provides formatted input in a fashion analogous to scanf.
  2083.               The difference is that scanf reads in a line of text from the
  2084.               stdlib standard input whereas you pass the address of a sequence
  2085.               of characters to SScanf in es:di.
  2086.  
  2087.  
  2088. Include:                stdlib.a
  2089.  
  2090.  
  2091.  
  2092.  
  2093. Routine:  ToLower
  2094. -----------------
  2095.  
  2096. Category:            Conversion Routine
  2097.  
  2098. Register on entry:   AL- Character to (possibly) convert
  2099.                 to lower case.
  2100.  
  2101. Register on return:  AL- Converted character.
  2102.  
  2103. Flags affected:      None
  2104.  
  2105. Example of usage:
  2106.              mov     al, char
  2107.              ToLower
  2108.  
  2109.  
  2110. Description:  ToLower checks the character in the AL register, if it is upper
  2111.           case it converts it to lower case.  If it is anything else,
  2112.           ToLower leaves the value in AL unchanged.  For high performance
  2113.           this routine is implemented as a macro rather than as a
  2114.           procedure call.  This routine is so short you would spend more
  2115.           time actually calling the routine than executing the code inside.
  2116.           However, the code is definitely longer than a (far) procedure
  2117.           call, so if space is critical and you're invoking this code
  2118.           several times, you may want to convert it to a procedure call to
  2119.           save a little space.
  2120.  
  2121.  
  2122. Include:             stdlib.a
  2123.  
  2124.  
  2125.  
  2126. Routine:   ToUpper
  2127. ------------------
  2128.  
  2129. Category:             Conversion Routine
  2130.  
  2131. Registers on Entry:   AL- Character to (possibly) convert to upper case
  2132.  
  2133. Registers on Return:  AL- Converted character
  2134.  
  2135. Flags Affected:       None
  2136.  
  2137. Example of Usage:
  2138.               mov  al, char
  2139.               ToUpper
  2140.  
  2141.  
  2142. Description:  ToUpper checks the character in the AL register, if it is lower
  2143.           case it converts it to upper case.  If it is anything else,
  2144.           ToUpper leaves the value in AL unchanged.  For high performance
  2145.           this routine is implemented as a macro rather than as a
  2146.           procedure call (see ToLower, above).
  2147.  
  2148.  
  2149. Include:              stdlib.a
  2150.  
  2151.  
  2152.  
  2153.  
  2154.  
  2155. Utility Routines
  2156. ----------------
  2157.  
  2158. The following routines are all Utility Routines.  The first routines listed
  2159. below compute the number of print positions required by a 16-bit and 32-bit
  2160. signed and unsigned integer value.  UlSize is like the LSize except it treats
  2161. the value in DX:AX as an unsigned long integer.  The next set of routines in
  2162. this section check the character in the AL register to see whether it is a
  2163. hexidecimal digit, if it alphabetic, if it is a lower case alphabetic, if it
  2164. is a upper case alphabetic, and if it is numeric.
  2165.  
  2166.  
  2167.  
  2168.  
  2169. Routine:  ISize
  2170. ---------------
  2171.  
  2172. Category:            Utility Routine
  2173.  
  2174. Register on entry:   AX- 16-bit value to compute the
  2175.                 output size for.
  2176.  
  2177. Register on return:  AX- Number of print positions
  2178.                 required by this number (including
  2179.                 the minus sign, if necessary).
  2180.  
  2181. Flags affected:      None
  2182.  
  2183. Example of usage:
  2184.              mov     ax, I
  2185.              ISize
  2186.              puti                    ;Prints positions
  2187.                          ;req'd by I.
  2188.  
  2189.  
  2190. Description:         This routine computes the number of print positions
  2191.              required by a 16-bit signed integer value.  ISize computes
  2192.              the minimum number of character positions it takes to print
  2193.              the signed decimal value in the AX register.  If the number
  2194.              is negative, it will include space for the minus sign in
  2195.              the count.
  2196.  
  2197.  
  2198. Include:             stdlib.a
  2199.  
  2200.  
  2201.  
  2202.  
  2203. Routine:  USize
  2204. ---------------
  2205.  
  2206. Category:            Utility Routine
  2207.  
  2208. Register on entry:   AX- 16 bit value to compute the
  2209.                 output size for
  2210.  
  2211. Register on return:  AX- number of print positions
  2212.              required by this number (including
  2213.              the minus sign, if necessary)
  2214.  
  2215. Flags affected:      None
  2216.  
  2217. Example of usage:
  2218.              mov     ax, I
  2219.              USize
  2220.              puti                    ;prints position
  2221.                          ;required by I
  2222.  
  2223.  
  2224. Description:         This routine computes the number of print positions
  2225.              required by a 16-bit signed integer value.  It also
  2226.              computes the number of print positions required by a
  2227.              16-bit unsigned value.  USize computes the minimum number
  2228.              of character positions it will take to print an unsigned
  2229.              decimal value in the AX register.  If the number is
  2230.              negative, it will include space for the minus sign in the
  2231.              count.
  2232.  
  2233.  
  2234. Include:             stdlib.a
  2235.  
  2236.  
  2237. Routine:  LSize
  2238. ---------------
  2239.  
  2240. Category:            Utility Routine
  2241.  
  2242. Register on entry:   DX:AX   - 32-bit value to compute the
  2243.                    output size for.
  2244.  
  2245. Register on return:  AX - Number of print positions
  2246.               required by this number (including
  2247.               the minus sign, if necessary).
  2248.  
  2249. Flags affected:      None
  2250.  
  2251. Example of Usage:
  2252.              mov     ax, word ptr L
  2253.              mov     dx, word ptr L+2
  2254.              LSize
  2255.              puti                    ;Prints positions
  2256.                          ;req'd by L.
  2257.  
  2258.  
  2259. Description:         This routine computes the number of print positions
  2260.              required by a 32-bit signed integer value.  LSize computes
  2261.              the minimum number of character positions it will take to
  2262.              print the signed decimal value in the DX:AX registers.  If
  2263.              the number is negative, it will include space for the minus
  2264.              sign in the count.
  2265.  
  2266.  
  2267. Include:             stdlib.a
  2268.  
  2269.  
  2270.  
  2271. Routine:  ULSize
  2272. ----------------
  2273.  
  2274. Category:             Utility Routine
  2275.  
  2276. Registers on Entry:   DX:AX - 32-bit value to compute the output size for.
  2277.  
  2278. Registers on return:  AX - number of print positions required by this number
  2279.  
  2280. Flags affected:       None
  2281.  
  2282. Example of Usage:
  2283.               mov     ax, word ptr L
  2284.               mov     dx, word ptr L+2
  2285.               ULSize
  2286.               puti                    ; Prints positions req'd by L
  2287.  
  2288.  
  2289. Description:          ULSize computes the minimum number of character
  2290.               positions it will take to print an unsigned decimal
  2291.               value in the DX:AX registers.
  2292.  
  2293.  
  2294. Include:              stdlib.a
  2295.  
  2296.  
  2297.  
  2298. Routine:  IsAlNum
  2299. -----------------
  2300.  
  2301. Category:             Utility routine
  2302.  
  2303. Register on entry:    AL - character to check.
  2304.  
  2305. Register on return:   None
  2306.  
  2307. Flags affected:       Zero flag - set if character is alphanumeric,
  2308.               clear if not.
  2309.  
  2310.  
  2311. Example of usage :    mov al, char
  2312.               IsAlNum
  2313.               je IsAlNumChar
  2314.  
  2315.  
  2316. Description :         This routine checks the character in the AL register to
  2317.               see if it is in the range A-Z, a-z, or 0-9.  Upon return,
  2318.               you can use the JE instruction to check to see if the
  2319.               character was in this range (or, conversely, you can use
  2320.               JNE to see if it is not in range).
  2321.  
  2322.  
  2323. Include:              stdlib.a
  2324.  
  2325.  
  2326. Routine:  IsXDigit
  2327. ------------------
  2328.  
  2329. Category:               Utility Routine
  2330.  
  2331. Register on Entry:     AL- character to check
  2332.  
  2333. Registers on Return:    None
  2334.  
  2335. Flags Affected:         Zero flag-  Set if character is a hex digit, clear if not
  2336.  
  2337.  
  2338. Example of Usage:       mov    al, char
  2339.             IsXDigit
  2340.             je     IsXDigitChar
  2341.  
  2342.  
  2343. Description:            This routine checks the character in the AL register to
  2344.             see if it is in the range A-F, a-f, or 0-9.  Upon
  2345.             return, you can use the JE instruction to check to see
  2346.             if the character was in this range (or, conversely,
  2347.             you can use jne to see if it is not in the range).
  2348.  
  2349.  
  2350. Include:                stdlib.a
  2351.  
  2352.  
  2353. Routine:   IsDigit
  2354. ------------------
  2355.  
  2356. Category:            Utility Routine
  2357.  
  2358. Register on entry:   AL- Character to check
  2359.  
  2360. Register on return:  None
  2361.  
  2362. Flags affected:         Zero flag- set if character is numeric, clear if not.
  2363.  
  2364. Example of Usage:    mov   al, char
  2365.              IsDigit
  2366.              je  IsDecChar
  2367.  
  2368.  
  2369. Description:         This routine checks the character in the AL register to
  2370.              see if it is in the range 0-9.  Upon return, you can use
  2371.              the JE instruction to check to see if the character was
  2372.              in the range (or, conversely, you can use JNE to see if it
  2373.              is not in the range).
  2374.  
  2375.  
  2376. Include:             stdlib.a
  2377.  
  2378.  
  2379. Routine:   IsAlpha
  2380. ------------------
  2381.  
  2382. Category:            Utility Routine
  2383.  
  2384. Register on entry:   AL- Character to check
  2385.  
  2386. Register on return:  None
  2387.  
  2388. Flags affected:         Zero flag- set if character is alphabetic, clear if not.
  2389.  
  2390. Example of Usage:    mov   al, char
  2391.              IsAlpha
  2392.              je   IsAlChar
  2393.  
  2394.  
  2395. Description:         This routine checks the character in the AL register to
  2396.              see if it is in the range A-Z or a-z.  Upon return, you
  2397.              can use the JE instruction to check to see if the character
  2398.              was in the range (or, conversely, you can use JNE to see
  2399.              if it is not in the range).
  2400.  
  2401. Include:             stdlib.a
  2402.  
  2403.  
  2404.  
  2405.  
  2406. Routine: IsLower
  2407. ----------------
  2408.  
  2409. Category:             Utility Routine
  2410.  
  2411. Registers on Entry:   AL- character to test
  2412.  
  2413. Registers on Return:  None
  2414.  
  2415.  
  2416. Flags Affected:       Zero = 1 if character is a lower case alphabetic character
  2417.               Zero = 0 if character is not a lower case alphabetic
  2418.               character
  2419.  
  2420. Example of Usage:     mov  AL, char        ; put char in AL
  2421.               IsLower              ; is char lower a-z?
  2422.               je  IsLowerChar      ; if yes, jump to IsLowerChar
  2423.  
  2424.  
  2425. Description:          This routine checks the character in the AL register to
  2426.               see if it is in the range a-z.  Upon return, you can use
  2427.               the JE instruction to check and see if the character was
  2428.               in this range (or you can use JNE to check and see if
  2429.               the character was not in this range).  This procedure is
  2430.               implemented as a macro for high performance.
  2431.  
  2432.  
  2433. Include:              stdlib.a
  2434.  
  2435.  
  2436. Routine:  IsUpper
  2437. -----------------
  2438.  
  2439. Category:             Utility Routine
  2440.  
  2441. Registers on Entry:   AL- character to check
  2442.  
  2443. Registers on Return:  None
  2444.  
  2445. Flags Affected:       Zero flag - set if character is uppercase alpha, clear
  2446.                   if not.
  2447.  
  2448.  
  2449. Example of Usage:     mov al, char
  2450.               IsUpper
  2451.               je IsUpperChar
  2452.  
  2453.  
  2454. Description:          This routine checks the character in the AL register to
  2455.               see if it is in the ranger A-Z.  Upon return, you can use
  2456.               the JE instruction to check to see if it not in the
  2457.               range).  It uses macro implementation for high performance.
  2458.  
  2459.  
  2460. Include:              stdlib.a
  2461.  
  2462.  
  2463. Routine:  Argc
  2464. --------------
  2465.  
  2466. Category:             Utility Routine
  2467.  
  2468. Registers on Entry:   None
  2469.  
  2470. Registers on Return:  CX-    Number of command line parameters
  2471.  
  2472. Flags Affected:       None
  2473.  
  2474.  
  2475. Example of Usage:     
  2476.             print
  2477.             db    "There were ",0
  2478.             argc
  2479.             mov    ax, cx
  2480.             puti
  2481.             print
  2482.             db    " command line parameters here",cr,lf,0
  2483.  
  2484. Description:    This routine returns the number of command line para-
  2485.         meters on the DOS command line.  Note that strings enclosed
  2486.         in quotation marks or apostrophes are counted as a single
  2487.         command line parameter.
  2488.  
  2489.  
  2490. Include:              stdlib.a
  2491.  
  2492.  
  2493. Routine:  Argv
  2494. --------------
  2495.  
  2496. Category:             Utility Routine
  2497.  
  2498. Registers on Entry:   AX-    Which parameter to grab (1..n).
  2499.               PSP-    Global variable containing the DOS program
  2500.                 segment prefix value.
  2501.  
  2502. Registers on Return:  ES:DI-    Pointer to string on heap containing the
  2503.                 specified parameter (empty string if the
  2504.                 parameter does not exist).
  2505.  
  2506. Flags Affected:       carry-    Set if malloc error.
  2507.  
  2508.  
  2509. Example of Usage:     
  2510.             mov    ax, 2
  2511.             argv
  2512.             print
  2513.             db    "The second command line parameter is ",0
  2514.             puts
  2515.             free
  2516.  
  2517. Description:    
  2518.  This routine returns a string containing the specified command line argument.
  2519. You must pass the position number of the argument in AX; this routine returns
  2520. the specified string on the heap with ES:DI pointing at the string.  Note that
  2521. the command line parameters are numbered starting from one.  If you specify an
  2522. out of range value, this routine returns a pointer to a zero byte (the empty
  2523. string).
  2524.  
  2525.  
  2526. Include:              stdlib.a
  2527.  
  2528.  
  2529.  
  2530. String Handling Routines
  2531. ------------------------
  2532.  
  2533. Manipulating text is a major part of many computer applications. Typically,
  2534. strings are inputed and interpreted. This interpretation may involve some
  2535. chores such as extracting certain part of the text, copying it, or comparing
  2536. with other strings.
  2537.  
  2538. The string manipulation routines in C provides various functions. Therefore,
  2539. the stdlib has some C-like string handling functions (e.g. strcpy, strcmp).
  2540. In C a string is an array of characters; similarly, the string are terminated
  2541. by a "0" as a null character. In general, the input strings of these routines
  2542. are pointed by ES:DI. In some routines, the carry flag will be set to indicate
  2543. an error.
  2544.  
  2545. The following string routines take as many as four different forms: strxxx,
  2546. strxxxl, strxxxm, and strxxxlm.  These routines differ in how they store
  2547. the destination string into memory and where they obtain their source strings.
  2548.  
  2549. Routines of the form strxxx generally expect a single source string address
  2550. in ES:DI or a source and destination string in ES:DI & DX:SI.  If these
  2551. routines produce a string, they generally store the result into the buffer
  2552. pointed at by ES:DI upon entry.  They return with ES:DI pointing at the
  2553. first character of the destination string.
  2554.  
  2555. Routines of the form strxxxl have a "literal source string".  A literal
  2556. source string follows the call to the routine in the code stream.  E.g.,
  2557.  
  2558.             strcatl
  2559.             db    "Add this string to ES:DI",0
  2560.  
  2561. Routines of the form strxxxm automatically allocate storage for a source
  2562. string on the heap and return a pointer to this string in ES:DI.
  2563.  
  2564. Routines of the form strxxxlm have a literal source string in the code
  2565. stream and allocate storage for the destination string on the heap.
  2566.  
  2567.  
  2568.  
  2569. Routine:  Strcpy (l)
  2570. --------------------
  2571.  
  2572. Category:             String Handling Routine
  2573.  
  2574. Registers on Entry:   ES:DI - pointer to source string (Strcpy only)
  2575.               CS:RET - pointer to  source  string (Strcpy1 only)
  2576.               DX:SI - pointer to destination string
  2577.  
  2578.  
  2579. Registers on return:  ES:DI - points at the destination string
  2580.  
  2581.  
  2582. Flags affected:          None
  2583.  
  2584.  
  2585. Example of Usage:
  2586.               mov     dx, seg Dest
  2587.               mov     si, offset Dest
  2588.               mov     di, seg Source
  2589.               mov     es, di
  2590.               mov     si, offset Source
  2591.               Strcpy
  2592.  
  2593.               mov     dx, seg Dest
  2594.               mov     si, offset Dest
  2595.               Strcpyl
  2596.               db      "String to copy",0
  2597.  
  2598.  
  2599. Description:  Strcpy is used to copy a zero-terminated string from one
  2600.           location to another.  ES:DI points at the source string,
  2601.           DX:SI points at the destination address.  Strcpy copies all
  2602.           bytes, up to and including the zero byte, from the source
  2603.           address to the destination address.  The target buffer must
  2604.           be large enough to hold the string.  Strcpy performs no error
  2605.           checking on the size of the destination buffer.
  2606.  
  2607.           Strcpyl copies the  zero-terminated string immediately following
  2608.           the call instruction to the destination address specified by
  2609.           DX:SI.  Again, this routine expects you to ensure that the
  2610.           taraget buffer is large enough to hold the result.
  2611.  
  2612.           Note: There are no "Strcpym" or "Strcpylm" routines.  The
  2613.           reason is simple: "StrDup" and "StrDupl" provide these functions
  2614.           using names which are familiar to MSC and Borland C users.
  2615.  
  2616. Include:              stdlib.a
  2617.  
  2618.  
  2619. Routine:  StrDup (l)
  2620. --------------------
  2621.  
  2622. Category:            String Handling Routine
  2623.  
  2624. Register on entry:   ES:dI - pointer to source string (StrDup
  2625.              only).  CS:RET - Pointer to source string
  2626.              (StrDupl only).
  2627.  
  2628. Register on return:  ES:DI - Points at the destination string
  2629.              allocated on heap.  Carry=0 if operation
  2630.              successful.  Carry=0 if insufficient
  2631.              memory for new string.
  2632.  
  2633. Flags affected:      Carry flag
  2634.  
  2635. Example of usage:
  2636.              StrDupl
  2637.              db "String for StrDupl",0
  2638.              jc  MallocError
  2639.              mov word ptr Dest1, di
  2640.              mov word ptr Dest1+2, es  ;create another
  2641.                            ;copy of this
  2642.                            ;string. Note
  2643.                            ;that es:di points
  2644.                            ;at Dest1 upon
  2645.                            ;entry to StrDup,
  2646.                            ;but it points at
  2647.                            ;the new string on
  2648.                            ;exit
  2649.              StrDup
  2650.              jc MallocError
  2651.              mov word ptr Dest2, di
  2652.              mov word ptr Dest2+2, es
  2653.  
  2654.  
  2655. Description:  StrDup and StrDupl duplicate strings.  You pass them
  2656.           a pointer to the string (in es:di for strdup, via
  2657.           the return address for strdupl) and they allocate
  2658.           sufficient storage on the heap for a copy of this
  2659.           string.  Then these two routines copy their source
  2660.           strings to the newly allocated storage and return
  2661.           a pointer to the new string in ES:DI.
  2662.  
  2663.  
  2664. Include:             stdlib.a
  2665.  
  2666.  
  2667. Routine:  Strlen
  2668. ----------------
  2669.  
  2670. Category:            String Handling Routine
  2671.  
  2672. Registers on entry:  ES:DI - pointer to source string.
  2673.  
  2674. Register on return:  CX - length of specified string.
  2675.  
  2676. Flags Affected:      None
  2677.  
  2678. Examples of Usage:
  2679.              les   di, String
  2680.              strlen
  2681.              mov   sl, cx
  2682.              printf
  2683.              db   "Length of '%s' is %d\n",0
  2684.              dd   String, sl
  2685.  
  2686.  
  2687. Description:  Strlen computes the length of the string whose address
  2688.           appears in ES:DI.  It returns the number of characters
  2689.           up to, but not including, the zero terminating byte.
  2690.  
  2691. Include:             stdlib.a
  2692.  
  2693.  
  2694. Routine:  Strcat (m,l,ml)
  2695. -------------------------
  2696.  
  2697. Category:             String Handling Routine
  2698.  
  2699. Registers on Entry:   ES:DI- Pointer to first string
  2700.               DX:SI- Pointer to second string (Strcat and Strcatm only)
  2701.  
  2702.  
  2703. Registers on Return:  ES:DI- Pointer to new string (Strcatm and Strcatml only)
  2704.  
  2705. Flags Affected:       Carry = 0 if no error
  2706.               Carry = 1 if insufficient memory (Strcatm and Strcatml
  2707.                             only)
  2708.  
  2709.  
  2710. Example of Usage:     les  DI, String1
  2711.               mov  DX, seg String2
  2712.               lea  SI, String2
  2713.               Strcat                   ; String1 <- String1 + String2
  2714.  
  2715.               les  DI, String1
  2716.               Strcatl                  ; String1 <- String1 +
  2717.               db  "Appended String",0  ;            "Appended String",0
  2718.  
  2719.  
  2720.               les  DI, String1
  2721.               mov  DX, seg String2
  2722.               lea  SI, String2
  2723.               Strcatm                  ; NewString <- String1 + String2
  2724.               puts
  2725.               free
  2726.  
  2727.               les  DI, String1
  2728.               Strcatml                 ; NewString <- String1 +
  2729.               db  "Appended String",0  ;         "Appended String",0
  2730.               puts
  2731.               free
  2732.  
  2733.  
  2734. Description:  These routines concatenate two strings together.  They differ
  2735.           mainly in the location of their source and destination operands.
  2736.  
  2737.           Strcat concatenates the string pointed at by DX:SI to the end of
  2738.           the string pointed at by ES:DI in memory.  Both strings must be
  2739.           zero-terminated.  The buffer pointed at by ES:DI must be large
  2740.           enough to hold the resulting string.  Strcat does NOT perform
  2741.           bounds checking on the data.
  2742.  
  2743.           ( continued on next page )
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751. Routine:  Strcat (m,l,ml)   ( continued )
  2752. -----------------------------------------
  2753.  
  2754.  
  2755.           Strcatm computes the length of the two strings pointed at by ES:DI
  2756.           and DX:SI and attempts to allocate this much storage on the heap.
  2757.           If it is not successful, Strcatm returns with the Carry flag set,
  2758.           otherwise it copies the string pointed at by ES:DI to the heap,
  2759.           concatenates the string DX:SI points at to the end of this string
  2760.           on the heap, and returns with the Carry flag clear and ES:DI
  2761.           pointing at the new (concatenated) string on the heap.
  2762.  
  2763.           Strcatl and Strcatml work just like Strcat and Strcatm except you
  2764.           supply the second string as a literal constant immediately AFTER
  2765.           the call rather than pointing DX:SI at it (see examples above).
  2766.  
  2767.  
  2768. Include:             stdlib.a
  2769.  
  2770.  
  2771. Routine:  Strchr
  2772. ----------------
  2773.  
  2774. Category:            String Handling Routine
  2775.  
  2776. Register on entry:   ES:DI- Pointer to string.
  2777.             AL- Character to search for.
  2778.  
  2779. Register on return:  CX- Position (starting at zero)
  2780.              where Strchr found the character.
  2781.  
  2782. Flags affected:      Carry=0 if Strchr found the character.
  2783.              Carry=1 if the character was not present
  2784.                  in the string.
  2785.  
  2786. Example of usage:
  2787.              les di, String
  2788.              mov al, Char2Find
  2789.              Strchr
  2790.              jc  NotPresent
  2791.              mov CharPosn, cx
  2792.  
  2793.  
  2794. Description:  Strchr locates the first occurrence of a character within a
  2795.           string.  It searches through the zero-terminated string pointed
  2796.           at by es:di for the character passed in AL. If it locates the
  2797.           character, it returns the position of that character to the CX
  2798.           register.  The first character in the string corresponds to the
  2799.           location zero.  If the character is not in the string, Strchr
  2800.           returns the carry flag set.  CX's value is undefined in that
  2801.           case.  If Strchr locates the character in the string, it
  2802.           returns with the carry clear.
  2803.  
  2804.  
  2805. Include:             stdlib.a
  2806.  
  2807.  
  2808. Routine:  Strstr (l)
  2809. --------------------
  2810.  
  2811. Category:            String Handling Routine
  2812.  
  2813. Register on entry:   ES:DI - Pointer to string.
  2814.              DX:SI - Pointer to substring(strstr).
  2815.              CS:RET - Pointer to substring (strstrl).
  2816.  
  2817. Register on return:  CX - Position (starting at zero)
  2818.              where Strstr/Strstrl found the
  2819.              character.  Carry=0 if Strstr/
  2820.              Strstrl found the character.
  2821.              Carry=1 if the character was not
  2822.              present in the string.
  2823.  
  2824. Flags affected:      Carry flag
  2825.  
  2826. Example of usage :
  2827.              les di, MainString
  2828.              lea si, Substring
  2829.              mov dx, seg Substring
  2830.              Strstr
  2831.              jc NoMatch
  2832.              mov i, cx
  2833.              printf
  2834.              db "Found the substring '%s' at location %i\n",0
  2835.              dd Substring, i
  2836.  
  2837.  
  2838. Description:  Strstr searches for the position of a substring
  2839.           within another string.  ES:DI points at the
  2840.           string to search through, DX:SI points at the
  2841.           substring.  Strstr returns the index into ES:DI's
  2842.           string where DX:SI's string is found.  If the
  2843.           string is found, Strstr returns with the carry
  2844.           flag clear and CX contains the (zero based) index
  2845.           into the string.  If Strstr cannot locate the
  2846.           substring within the string ES:DI points at, it
  2847.           returns the carry flag set.  Strstrl works just
  2848.           like Strstr except it excepts the substring to
  2849.           search for immediately after the call instruction
  2850.           (rather than passing this address in DX:SI).
  2851.  
  2852.  
  2853. Include:              stdlib.a
  2854.  
  2855.  
  2856. Routine:  Strcmp (l)
  2857. --------------------
  2858.  
  2859. Category:            String Handling Routine
  2860.  
  2861. Registers on entry:  ES:DI contains the address of the first string
  2862.              DX:SI contains the address of the second string (strcmp)
  2863.              CS:RET (contains the address of the substring (strcmpl)
  2864.  
  2865. Register on return:  CX (contains the position where the two strings differ)
  2866.  
  2867. Flags affected:      Carry flag and zero flag (string1 > string2 if C + Z = 0)
  2868.                      (string1 < string2 if C = 1)
  2869.  
  2870. Example of Usage:
  2871.              les     di, String1
  2872.              mov     dx, seg String2
  2873.              lea     si, String2
  2874.              strcmp
  2875.              ja        OverThere
  2876.  
  2877.              les     di, String1
  2878.              strcmpl
  2879.              db     "Hello",0
  2880.              jbe     elsewhere
  2881.  
  2882.  
  2883.  
  2884. Description:  Strcmp compares the first strings pointed by ES:DI with
  2885.           the second string pointed by DX:SI. The carry and zero flag
  2886.           will contain the corresponding result. So unsigned branch
  2887.           instructions such as JA or JB is recommended. If string1
  2888.           equals string2, strcmp will return with CX containing the
  2889.           offset of the zero byte in the two strings.
  2890.  
  2891.           Strcmpl compares the first string pointed by ES:DI with
  2892.           the substring pointed by CS:RET. The carry and zero flag
  2893.           will contain the corresponding result. So unsigned branch
  2894.           instructions such as JA or JB are recommended. If string1
  2895.           equals to the substring, strcmp will return with CX
  2896.           containing the offset of the zero byte in the two strings.
  2897.  
  2898. Include:             stdlib.a
  2899.  
  2900.  
  2901. Routine:  Strupr (m)
  2902. --------------------
  2903.  
  2904. Category:            String Handling Routine
  2905.              Conversion Routine
  2906.  
  2907. Register on entry:   ES:DI (contains the pointer to input string)
  2908.  
  2909. Register on return:  ES:DI (contains the pointer to input string
  2910.                with characters converted to upper case)
  2911.                Note: struprm allocates storage for a new
  2912.                string on the heap and returns the pointer
  2913.                to this routine in ES:DI.
  2914.  
  2915. Flags affected:      Carry = 1 if memory allocation error (Struprm only).
  2916.  
  2917. Example of Usage:
  2918.              les     di, lwrstr1
  2919.              strupr
  2920.              puts
  2921.  
  2922.              mov        di, seg StrWLwr
  2923.              mov    es, di
  2924.              lea    di, StrWLwr
  2925.              struprm
  2926.              puts
  2927.              free
  2928.  
  2929.  
  2930. Description:  Strupr converts the input string pointed by ES:DI to
  2931.           upper case.  It will actually modify the string you pass
  2932.           to it.
  2933.  
  2934.           Struprm first makes a copy of the string on the heap and
  2935.           then converts the characters in this new string to upper
  2936.           case.  It returns a pointer to the new string in ES:DI.
  2937.  
  2938. Include:             stdlib.a
  2939.  
  2940.  
  2941. Routine:  Strlwr (m)
  2942. --------------------
  2943.  
  2944. Category:            String Handling Routine
  2945.              Conversion Routine
  2946.  
  2947. Register on entry:   ES:DI (contains the pointer to input string)
  2948.  
  2949. Register on return:  ES:DI (contains the pointer to input string
  2950.                with characters converted to lower case).
  2951.  
  2952. Flags affected:      Carry = 1 if memory allocation error (strlwrm only)
  2953.  
  2954.  
  2955. Example of Usage:
  2956.              les di, uprstr1
  2957.              strlwr
  2958.              puts
  2959.  
  2960.              mov        di, seg StrWLwr
  2961.              mov    es, di
  2962.              lea    di, StrWLwr
  2963.              strlwrm
  2964.              puts
  2965.              free
  2966.  
  2967.  
  2968.  
  2969.  
  2970. Description:  Strlwr converts the input string pointed by ES:DI to
  2971.           lower case. It will actually modify the string you pass
  2972.           to it.
  2973.  
  2974.           Strlwrm first copies the characters onto the heap and then
  2975.           returns a pointer to this string after converting all the
  2976.           alphabetic characters to lower case.
  2977.  
  2978.  
  2979. Include:             stdlib.a
  2980.  
  2981.  
  2982.  
  2983. Routine:  Strset (m)
  2984. --------------------
  2985.  
  2986. Category:            String Handling Routine
  2987.  
  2988. Register on entry:   ES:DI contains the pointer to input string (StrSet only)
  2989.              AL    contains the character to copy
  2990.              CX    contains number of characters to allocate for
  2991.                the string (Strsetm only)
  2992.  
  2993. Register on return:  ES:DI pointer to newly allocated string (Strsetm only)
  2994.  
  2995. Flags affected:      Carry set if memory allocation error (Strsetm only)
  2996.  
  2997. Example of Usage:
  2998.              les     di, string1
  2999.              mov    al, " "        ;Blank fill string.
  3000.              Strset
  3001.  
  3002.              mov     cx, 32
  3003.              mov    al, "*"        ;Create a new string w/32
  3004.              Strsetm            ; asterisks.
  3005.              puts
  3006.              free
  3007.  
  3008.  
  3009. Description:  Strset overwrites the data on input string pointed by
  3010.           ES:DI with the character on AL.
  3011.  
  3012.           Strsetm creates a new string on the heap with the number
  3013.           of characters specified in CX.  All characters in the string
  3014.           are initialized with the value in AL.
  3015.  
  3016. Include:             stdlib.a
  3017.  
  3018.  
  3019. Routine:  Strspan (l)
  3020. ---------------------
  3021.  
  3022. Category:             String Handling Routine
  3023.  
  3024. Registers on Entry:   ES:DI - Pointer to string to scan
  3025.               DX:SI - Pointer to character set (Strspan only)
  3026.               CS:RET- Pointer to character set (Strspanl only)
  3027.  
  3028. Registers on Return:  CX- First position in scanned string which does not
  3029.               contain one of the characters in the character set
  3030.  
  3031. Flags Affected:       None
  3032.  
  3033. Example of Usage:
  3034.               les  DI, String
  3035.               mov  DX, seg CharSet
  3036.               lea  SI, CharSet
  3037.               Strspan           ; find first position in String with a
  3038.               mov i, CX         ;                  char not in CharSet
  3039.               printf
  3040.               db  "The first char which is not in CharSet "
  3041.               db  "occurs at position %d in String.\n",0
  3042.               dd  i
  3043.  
  3044.               les  DI, String
  3045.               Strspanl          ; find first position in String which
  3046.               db   "aeiou",0    ; is not a vowel
  3047.               mov  j, CX
  3048.               printf
  3049.               db  "The first char which is not a vowel "
  3050.               db  "occurs at position %d in String.\n",0
  3051.               dd  j
  3052.  
  3053.  
  3054. Description:  Strspan(l) scans a string, counting the number of characters which
  3055.           are present in a second string (which represents a character set).
  3056.           ES:DI points at a zero-terminated string of characters to scan.
  3057.           DX:SI (strspan) or CS:RET (strspanl) points at another zero-
  3058.           terminated string containing the set of characters to compare
  3059.           against.  The position of the first character in the string
  3060.           pointed to by ES:DI which is NOT in the character set is returned.
  3061.           If all the characters in the string are in the character set, the
  3062.           position of the zero-terminating byte will be returned.
  3063.  
  3064.           Although strspan and (especially) strspanl are very compact and
  3065.           convenient to use, they are not particularly efficient.  The
  3066.           character set routines provide a much faster alternative at the
  3067.           expense of a little more space.
  3068.  
  3069.  
  3070. Include:               stdlib.a
  3071.  
  3072.  
  3073. Routine:  Strcspan, Strcspanl
  3074. -----------------------------
  3075.  
  3076. Category:             String Handling Routine
  3077.  
  3078. Registers on Entry:   ES:DI - Pointer to string to scan
  3079.               DX:SI - Pointer to character set (Strcspan only)
  3080.               CS:RET- Pointer to character set (Strcspanl only)
  3081.  
  3082. Registers on Return:  CX- First position in scanned string which contains one
  3083.               of the characters in the character set
  3084.  
  3085. Flags Affected:       None
  3086.  
  3087. Example of Usage:
  3088.               les  DI, String
  3089.               mov  DX, seg CharSet
  3090.               lea  SI, CharSet
  3091.               Strcspan          ; find first position in String with a
  3092.               mov i, CX         ;                      char in CharSet
  3093.               printf
  3094.               db  "The first char which is in CharSet "
  3095.               db  "occurs at position %d in String.\n",0
  3096.               dd  i
  3097.  
  3098.               les  DI, String
  3099.               Strcspanl         ; find first position in String which
  3100.               db   "aeiou",0    ; is a vowel.
  3101.               mov  j, CX
  3102.               printf
  3103.               db  "The first char which is a vowel occurs "
  3104.               db  "at position %d in String.\n",0
  3105.               dd  j
  3106.  
  3107.  
  3108. Description:  Strcspan(l) scans a string, counting the number of characters
  3109.           which are NOT present in a second string (which represents a
  3110.           character set).  ES:DI points at a zero-terminated string of
  3111.           characters to scan.  DX:SI (strcspan) or CS:RET (strcspanl) points
  3112.           at another zero-terminated string containing the set of characters
  3113.           to compare against.  The position of the first character in the
  3114.           string pointed to by ES:DI which is in the character set is
  3115.           returned.  If all the characters in the string are not in the
  3116.           character set, the position of the zero-terminating byte will be
  3117.           returned.
  3118.  
  3119.           Although strcspan and strcspanl are very compact and convenient to
  3120.           use, they are not particularly efficient.  The character set
  3121.           routines provide a much faster alternative at the expense of a
  3122.           little more space.
  3123.  
  3124. Include:              stdlib.a
  3125.  
  3126.  
  3127. Routine:  StrIns (m,l,ml)
  3128. -------------------------
  3129.  
  3130. Category:             String Handling Routine
  3131.  
  3132. Registers on Entry:   ES:DI - Pointer to destination string (to insert into)
  3133.               DX:SI - Pointer to string to insert
  3134.                       (StrIns and StrInsm only)
  3135.               CX    - Insertion point in destination string
  3136.  
  3137. Registers on Return:  ES:DI - Pointer to new string (StrInsm and StrInsml only)
  3138.  
  3139. Flags Affected:       Carry = 0 if no error
  3140.               Carry = 1 if insufficient memory
  3141.                    (StrInsm and StrInsml only)
  3142.  
  3143.  
  3144. Example of Usage:
  3145.               les  DI, DestStr
  3146.               mov  DX, word ptr SrcStr+2
  3147.               mov  SI, word ptr SrcStr
  3148.               mov  CX, 5
  3149.               StrIns     ; Insert SrcStr before the 6th char of DestStr
  3150.  
  3151.               les  DI, DestStr
  3152.               mov  CX, 2
  3153.               StrInsl    ; Insert "Hello" before the 3rd char of DestStr
  3154.               db  "Hello",0
  3155.  
  3156.               les  DI, DestStr
  3157.               mov  DX, word ptr SrcStr+2
  3158.               mov  SI, word ptr SrcStr
  3159.               mov  CX, 11
  3160.               StrInsm      ; Create a new string by inserting SrcStr
  3161.                    ;         before the 12th char of DestStr
  3162.               puts
  3163.               putcr
  3164.               free
  3165.  
  3166.  
  3167. Description:  These routines insert one string into another string.  ES:DI
  3168.           points at the string into which you want to insert another.  CX
  3169.           contains the position (or index) where you want the string
  3170.           inserted.  This index is zero-based, so if CX contains zero, the
  3171.           source string will be inserted before the first character in the
  3172.           destination string.  If CX contains a value larger than the size
  3173.           of the destination string, the source string will be appended to
  3174.           the destination string.
  3175.  
  3176.           StrIns inserts the string pointed at by DX:SI into the string
  3177.           pointed at by ES:DI at position CX.  The buffer pointed at by
  3178.           ES:DI must be large enough to hold the resulting string.  StrIns
  3179.           does NOT perform bounds checking on the data.
  3180.  
  3181.      ( continued on next page )
  3182.  
  3183.  
  3184. Routine:  StrIns (m,l,ml)   ( continued )
  3185. -----------------------------------------
  3186.  
  3187.           StrInsm does not modify the source or destination strings, but
  3188.           instead attempts to allocate a new buffer on the heap to hold the
  3189.           resulting string.  If it is not successful, StrInsm returns with
  3190.           the Carry flag set, otherwise the resulting string is created and
  3191.           its address is returned in the ES:DI registers.
  3192.  
  3193.           StrInsl and StrInsml work just like StrIns and StrInsm except you
  3194.           supply the second string as a literal constant immediately AFTER
  3195.           the call rather than pointing DX:SI at it (see examples above).
  3196.  
  3197.  
  3198.  
  3199. Routine:  StrDel, StrDelm
  3200. -------------------------
  3201.  
  3202. Category:              String Handling Routine
  3203.  
  3204. Registers on Entry:    ES:DI -  pointer to string
  3205.                CX - deletion point in  string
  3206.                AX - number of characters to delete
  3207.  
  3208. Registers on return:   ES:DI - pointer to new string (StrDelm only)
  3209.  
  3210. Flags  affected:       Carry = 1 if memory allocation error,  0 if okay
  3211.                (StrDelm only).
  3212.  
  3213. Example of Usage:
  3214.                les     di,  Str2Del
  3215.                mov     cx,  3          ; Delete starting at 4th char
  3216.                mov     ax,  5          ; Delete five characters
  3217.                StrDel                  ; Delete in place
  3218.  
  3219.                les     di,  Str2Del2
  3220.                mov     cx,  5
  3221.                mov     ax,  12
  3222.                StrDelm
  3223.                puts
  3224.                free
  3225.  
  3226.  
  3227. Description:  StrDel deletes characters from a string.  It works by computing
  3228.           the beginning and end of the deletion point.  Then it copies all
  3229.           the characters from the end of the deletion point to the end of
  3230.           the string (including the zero byte) to the beginning of the
  3231.           deletion point.  This covers up (thereby effectively deleting)
  3232.           the undesired characters in the string.
  3233.  
  3234.           Here are two degenerate cases to worry about -- 1) when you
  3235.           specify a deletion point which is beyond the end of the string;
  3236.           and 2) when the deletion point is within the string but the
  3237.           length of the deletion takes you beyond the end of the string.
  3238.           In the first case StrDel simply ignores the deletion request.  It
  3239.           does not modify the original string.  In the second case,
  3240.           StrDel simply deletes everything from the deletion point to the
  3241.           end of the string.
  3242.  
  3243.           StrDelm works just like StrDel except it does not delete the
  3244.           characters in place.  Instead, it creates a new string on the
  3245.           heap consisting of the characters up to the deletion point and
  3246.           those following the characters to delete.  It returns a pointer
  3247.           to the new string on the heap in ES:DI, assuming that it
  3248.           properly allocated the storage on the heap.
  3249.  
  3250. Include:               stdlib.a
  3251.  
  3252.  
  3253. Routine:  StrRev, StrRevm
  3254. -------------------------
  3255.  
  3256. Author:               Michael Blaszczak (.B  ekiM)
  3257.  
  3258. Category:             String Handling Routine
  3259.  
  3260. Registers on Entry:   ES:DI - pointer to string
  3261.  
  3262. Registers on return:  ES:DI - pointer to new string (StrRevm only).
  3263.  
  3264. Flags affected:       Carry  = 1 if memory allocation error, 0 if okay
  3265.               (StrRevm only).
  3266.  
  3267. Example of Usage:
  3268.  
  3269. Description:  StrRev reverses the characters in a string.  StrRev reverses,
  3270.           in place, the characters in the string that ES:SI points at.
  3271.           StrRevm creates a new string on the heap (which contains the
  3272.           characters in the string ES:DI points at, only reversed) and
  3273.           returns a pointer to the new string in ES:DI.  If StrRevm
  3274.           cannot allocate sufficient memory for the string, it returns
  3275.           with the carry flag set.
  3276.  
  3277.  
  3278. Include:              stdlib.a
  3279.  
  3280.  
  3281. Routine:  ToHex
  3282. ---------------
  3283.  
  3284. Category:             String Handling Routine/ Conversion Routine
  3285.  
  3286. Registers on Entry:   ES:DI - pointer to byte array
  3287.               BX-     memory base address for bytes
  3288.               CX-     number of entries in byte array
  3289.  
  3290. Registers on return:  ES:DI - pointer to Intel Hex format string.
  3291.  
  3292. Flags affected:       Carry  = 1 if memory allocation error, 0 if okay
  3293.            
  3294.  
  3295. Example of Usage:
  3296.  
  3297.         mov    bx, 100h    ;Put data at address 100h in hex file.
  3298.         mov    cx, 10h        ;Total of 16 bytes in this array.
  3299.         les    di, Buffer    ;Pointer to data bytes
  3300.         ToHex            ;Convert to Intel HEX string format.
  3301.         puts            ;Print it.
  3302.  
  3303. Description:  
  3304.  
  3305. ToHex converts a stream of binary values to Intel Hex format.  Intel HEX format
  3306. is a common ASCII data interchange format for binary data.  It takes the
  3307. following form:
  3308.  
  3309.     : BB HHLL RR DDDD...DDDD SS <cr> <lf>
  3310.  
  3311. (Note:spaces were added for clarity, they are not actually present in the
  3312. hex string)
  3313.  
  3314. BB is a pair of hex digits which represent the number of data bytes (The DD
  3315. entries) and is the value passed in CX.
  3316.  
  3317. HHLL is the hexadecimal load address for these data bytes (passed in BX).
  3318.  
  3319. RR is the record type.  ToHex always produces data records with the RR field
  3320. containing "00".  If you need to output other field types (usually just an
  3321. end record) you must create that string yourself.  ToHex will not do it.
  3322.  
  3323. DD...DD is the actual data in hex form.  This is the number of bytes specified
  3324. in the BB field.
  3325.  
  3326. SS is the two's complement of the checksum (which is the sum of the binary
  3327. values of the BB, HH, LL, RR, and all DD fields).
  3328.  
  3329. This routine allocates storage for the string on the heap and returns a pointer
  3330. to that string in ES:DI.
  3331.  
  3332. Include:              stdlib.a
  3333.  
  3334.  
  3335. Memory Management Routines
  3336. --------------------------
  3337.  
  3338. The stdlib memory management routines let you dynamically allocate storage on
  3339. the heap.  These routines are somewhat similar to those provided by the "C"
  3340. programming language.  However, these routines do not perform garbage
  3341. collection, as this would introduce too many restrictions and have a very
  3342. adverse effect on speed.
  3343.  
  3344. The following paragraph gives a description of how the memory management
  3345. routines work.  These routines may be updated in future revisions, however,
  3346. so you should never make assumptions about the structure of the memory
  3347. management record (described below) or else your code may not work on the
  3348. next revision.
  3349.  
  3350. The allocation/deallocation routines should be fairly fast.  Malloc and free
  3351. use a modified first/next fit algorithm which lets the system quickly find a
  3352. memory block of the desired size without undue fragmentation problems (average
  3353. case).  The memory manager data structure has an overhead of eight bytes
  3354. (meaning each malloc operation requires at least eight more bytes than you ask
  3355. for) and a granularity of 16 bytes.  The overhead (eight bytes) per allocated
  3356. block may seem rather high, but that is part of the price to pay for faster
  3357. malloc and free routines.  All pointers are far pointers and each new item is
  3358. allocated on a paragraph boundary.  The current memory manager routines always
  3359. allocate (n+8) bytes, rounding up to the next multiple of 16 if the result is
  3360. not evenly divisible by sixteen.  The first eight bytes of the structure are
  3361. used by the memory management routines, the remaining bytes are available for
  3362. use by the caller (malloc, et. al., return a pointer to the first byte beyond
  3363. the memory management overhead structure).
  3364.  
  3365.  
  3366.  
  3367.  
  3368. Routine:  MemInit
  3369. -----------------
  3370.  
  3371. Category:               Memory Management Routine
  3372.  
  3373. Registers on Entry:     DX - number of paragraphs to reserve
  3374.  
  3375. Globals Affected:       zzzzzzseg - segment name of the last segment in your
  3376.                     program
  3377.             PSP - public word variable which holds the PSP value
  3378.                   for your program
  3379.  
  3380. Registers on return:    CX - number of paragraphs actually reserved by MemInit
  3381.  
  3382. Flags affected:         Carry = 0 if no error.
  3383.             Carry = 1 if error; AX contains DOS error code.
  3384.  
  3385.  
  3386. Example of Usage:
  3387.                         ; Don't forget to set up PSP
  3388.                         ; and zzzzzzseg before calling
  3389.                         ; MemInit
  3390.             mov     dx, dx          ; Allocate all available RAM
  3391.             MemInit
  3392.             jc      MemoryError     ; CX contains the number of
  3393.                         ; paragraphs actually
  3394.                         ; allocated
  3395.  
  3396.  
  3397. Description:  This routine initializes the memory manager system.  You must
  3398.           call it before using any routines which call any of the memory
  3399.           manager procedures (since a good number of the stdlib routines
  3400.           call the memory manager, you should get in the habit of always
  3401.           calling this routine.)  The system will "die a horrible death"
  3402.           if you call a memory manager routine (like malloc) without first
  3403.           calling MemInit.
  3404.  
  3405.           This routine expects you to define (and set up) two global
  3406.           names: zzzzzzseg and PSP.  "zzzzzzseg" is a dummy segment which
  3407.           must be the name of the very last segment defined in your
  3408.           program.  MemInit uses the name of this segment to determine the
  3409.           address of the last byte in your program.  If you do not
  3410.           declare this segment last, the memory manager will overwrite
  3411.           anything which follows zzzzzzseg.  The "shell.asm" file
  3412.           provides you with a template for your programs which properly
  3413.           defines this segment.
  3414.  
  3415.           PSP should be a word variable which contains the program segment
  3416.           prefix value for your  program.  MS-DOS passes the PSP value to
  3417.           your program in the DS and ES registers.  You should save this
  3418.           value in the PSP variable.  Don't forget to make PSP a public
  3419.           symbol in your main program's source file.  The "shell.asm" file
  3420.           demonstrates how to properly set up this value.
  3421.  
  3422.           The DX register contnains the number of 16-byte paragraphs you
  3423.           want to reserve for the heap.  If DX contains zero, MemInit will
  3424.           allocate all of the available memory to the heap.  If your
  3425.           program is going to allow the user to run a copy of the command
  3426.           interpreter, or if your program is going to EXEC some other
  3427.           program, you should not allocate all storage to the heap.
  3428.           Instead, you should reserve  some memory for those programs.
  3429.           By setting DX to some value other than zero, you can tell MemInit
  3430.           how much memory you want to reserve for the heap.  All left over
  3431.           memory will be available for other system (or program) use.
  3432.           If the value in DX is larger than the amount of available RAM,
  3433.           MemInit will split the available memory in half and reserve half
  3434.           for the heap leaving the other half unallocated.  If you want to
  3435.           force this situation (to leave half available memory for other
  3436.           purposes), simply load DX with 0FFFFH before calling MemInit.
  3437.           There will never be this much memory available, so this will
  3438.           force MemInit to split the available RAM between the heap and
  3439.           unallocated storage.
  3440.  
  3441.           On return from MemInit, the CX register contains the number of
  3442.           paragraphs actually allocated.  You can use this value to see if
  3443.           MemInit has actually allocated the number of paragraphs you
  3444.           requested.  You  can also use this value to determine how much
  3445.           space is available when you elect to split the free space
  3446.           between the heap and the unallocated portions.
  3447.  
  3448.           If all goes well, this routine returns the carry flag clear.
  3449.           If a DOS memory manager error occurs, this routine returns the
  3450.           carry flag set and the DOS error code in the AX register.
  3451.  
  3452.  
  3453. Include:                stdlib.a
  3454.  
  3455.  
  3456. Routine:  Malloc
  3457. ----------------
  3458.  
  3459. Category:              Memory Management Routine
  3460.  
  3461. Registers on Entry:    CX - number of bytes to reserve
  3462.  
  3463. Registers on return:   CX - number of bytes actually reserved by Malloc
  3464.                ES:DI - ptr to 1st byte of memory allocated by Malloc
  3465.  
  3466. Flags affected:        Carry=0 if no error.
  3467.                Carry=1 if insufficient memory.
  3468.  
  3469. Example of Usage:
  3470.                mov     cx, 256
  3471.                Malloc
  3472.                jnc     GoodMalloc
  3473.                print   db    "Insufficient memory to continue.",cr,lf,0
  3474.                jmp   Quit
  3475.       GoodMalloc:  mov   es:[di], 0          ;Init string to NULL
  3476.  
  3477.  
  3478. Description:  Malloc is the workhorse routine you use to allocate a block of
  3479.           memory.  You give it the number of bytes you need and if it
  3480.           finds a block large enough, it will  allocate the requested
  3481.           amount and return a pointer to that block.
  3482.  
  3483.           Most memory managers require  a small amount of overhead for each
  3484.           block they allocate.  Stdlib's (current) memory manager requires
  3485.           an overhead of eight bytes.  Furthermore, the grainularity is 16
  3486.           bytes.  This means that Malloc always allocates blocks of memory
  3487.           in paragraph multiples.  Therefore, Malloc may actually reserve
  3488.           more storage than you specify. Therefore, the value returned in
  3489.           CX may be somewhat greater than the requested value.  By setting
  3490.           the minimum allocation size to a paragraph, however, the
  3491.           overhead is reduced and the speed of Malloc is improved by a
  3492.           considerable amount.
  3493.  
  3494.           Stdlib's memory management does not do any garbage collection.
  3495.           Doing so would place too many demands on Malloc's users.
  3496.           Therefore, it is quite possible for you to fragment memory with
  3497.           multiple calls to maloc, realloc, and free.  You could wind up in
  3498.           a situation where there is enough free memory to satisfy your
  3499.           request, but there isn't a single contiguous block large enough
  3500.           for the request.  Malloc treats this as an insufficient memory
  3501.           error and returns with the carry flag set.
  3502.  
  3503.           If Malloc cannot allocate a block of the requested size, it
  3504.           returns with the carry flag set.  In this situation, the contents
  3505.           of ES:DI is undefined.  Attempting to dereference this pointer
  3506.           will produce erratic and, perhaps, disasterous results.
  3507.  
  3508. Include:              stdlib.a
  3509.  
  3510.  
  3511. Routine:  Realloc
  3512. -----------------
  3513.  
  3514. Category:  Memory Management Routine
  3515.  
  3516. Registers on Entry:   CX - number of bytes to reserve
  3517.               ES:DI - pointer to block to  reallocate.
  3518.  
  3519. Registers on return:  CX - number of bytes actually reserved by Realloc.
  3520.               ES:DI - pointer to first byte of memory allocated by
  3521.                   Realloc.
  3522.  
  3523. Flags affected:       Carry = 0 if no error.
  3524.               Carry = 1 if insufficient memory.
  3525.  
  3526. Example of Usage:
  3527.             mov    cx, 1024    ;Change block size to 1K
  3528.             les    di, CurPtr    ;Get address of block into ES:DI
  3529.             realloc
  3530.             jc    BadRealloc
  3531.             mov    word ptr CurPtr, di
  3532.             mov    word ptr CurPtr+2, es
  3533.  
  3534.  
  3535. Description:  Realloc lets you change the size of an allocated block in the
  3536.           heap.  It allows you to make the block larger or smaller.
  3537.           If you make the  block smaller, Realloc simply frees (returns
  3538.           to the heap) any leftover bytes at the end of the block.  If
  3539.           you make the block larger, Realloc goes out and allocates a
  3540.           block of the requested size, copies the bytes form the old
  3541.           block to the beginning of the new block (leaving the bytes at
  3542.           the end of the new block uninitialized)), and then frees the
  3543.           old block.
  3544.  
  3545.  
  3546. Include:               stdlib.a
  3547.  
  3548.  
  3549. Routine:  Free
  3550. --------------
  3551.  
  3552. Category:               Memory Management Routine
  3553.  
  3554. Registers on Entry:     ES:DI - pointer to block to deallocate
  3555.  
  3556. Registers on return:    None
  3557.  
  3558. Flags affected:         Carry = 0 if no error.
  3559.             Carry = 1 if ES:DI doesn't point at a Free block.
  3560.  
  3561. Example of Usage:
  3562.             les     di, HeapPtr
  3563.             Free
  3564.  
  3565. Description:  Free (possibly) deallocates storage allocated on the heap by
  3566.           malloc or Realloc.  Free returns this storage to heap so other
  3567.           code can reuse it later.  Note, however, that Free doesn't
  3568.           always return storage to the heap.  The memory manager data
  3569.           structure keeps track of the number of pointers currently
  3570.           pointing at a block on the heap (see DupPtr, below).  If you've
  3571.           set up several pointers such that they point at the same block,
  3572.           Free will not deallocate the storage until you've freed all of
  3573.           the pointers which point at the block.
  3574.  
  3575.           Free usually returns an error code (carry flag = 1) if you
  3576.           attempt to Free a block which is not currently allocated or if
  3577.           you pass it a memory address which was not returned by malloc
  3578.           (or Realloc).  By no means is this routine totally robust.
  3579.           If you start calling free with arbitrary pointers in es:di
  3580.           (which happen to be pointing into the heap) it is possible,
  3581.           under certain circumstances, to confuse Free and it will attempt
  3582.           to free a block it really should not.
  3583.  
  3584.           This problem could be solved by adding a large amount of extra
  3585.           code to the free routine, but it would slow it down considerably.
  3586.           Therefore, a little safety has been sacrificed for a lot of
  3587.           speed.  Just make sure your code is correct and everything will
  3588.           be fine!
  3589.  
  3590.  
  3591. Include:               stdlib.a
  3592.  
  3593.  
  3594. Routine:  DupPtr
  3595. ----------------
  3596.  
  3597. Category:             Memory Manager Routine
  3598.  
  3599. Registers on Entry:   ES:DI - pointer to block
  3600.  
  3601. Registers on return:  None
  3602.  
  3603. Flags affected:       Carry = 0 if no error.
  3604.               Carry = 1 if es:di doesn't point at a free block.
  3605.  
  3606. Example of Usage:
  3607.               les     di,  Ptr
  3608.               DupPtr
  3609.  
  3610.  
  3611. Description:  DupPtr increments the pointer count for the block at the
  3612.           specifiied address.  Malloc sets this counter to one.  Free
  3613.           decrements it by one.  If free decrements the value and it
  3614.           becomes zero, free will release the storage to the heap for
  3615.           other use.  By using DupPtr you can tell the memory manager
  3616.           that you have several pointers pointing  at the same block
  3617.           and that it shouldn't deallocate the storage until you free
  3618.           all of those pointers.
  3619.  
  3620.  
  3621. Include:              stdlib.a
  3622.  
  3623.  
  3624. Routine:  IsInHeap
  3625. ------------------
  3626.  
  3627. Category:             Memory Management Routine
  3628.  
  3629. Registers on Entry:   ES:DI - pointer to a block
  3630.  
  3631. Registers on return:  None
  3632.  
  3633. Flags affected:       Carry = 0 if ES:DI is a valid pointer.
  3634.               Carry = 1 if not.
  3635.  
  3636. Example of Usage:
  3637.             les    di, MemPtr
  3638.             IsInHeap
  3639.             jc    NotInHeap
  3640.  
  3641. Description:  This routine lets you know if es:di contains the address of
  3642.           a byte in the heap somewhere.  It does not tell you if es:di
  3643.           contains a valid pointer returned by malloc (see IsPtr, below).
  3644.           For example, if es:di contains the address of some particular
  3645.           element of an array (not necessarily the first element)
  3646.           allocated on the heap, IsInHeap will return with the carry clear
  3647.           denoting that the es:di points somewhere in the heap.  Keep in
  3648.           mind that calling this routine does not validate the pointer;
  3649.           it could be pointing at a byte which is part of the memory
  3650.           manager data structure rather than at actual data (since the
  3651.           memory manager maintains that informatnion within the
  3652.           bounds of the heap). This routine is mainly useful for seeing
  3653.           if something is allocated on the heap as opposed to somewhere
  3654.           else (like your code, data, or stack segment).
  3655.  
  3656.  
  3657. Include:              stdlib.a
  3658.  
  3659.  
  3660. Routine:  IsPtr
  3661. ---------------
  3662.  
  3663. Category:               Memory Management Routine
  3664.  
  3665. Registers on Entry:     ES:DI - pointer to block
  3666.  
  3667. Registers on return:    None
  3668.  
  3669. Flags affected:         Carry = 0 if es:di is a valid pointer.
  3670.             Carry = 1 if not.
  3671.  
  3672. Example of Usage:
  3673.             les    di, MemPtr
  3674.             IsPtr
  3675.             jc    NotAPtr
  3676.  
  3677.  
  3678.  
  3679. Description:  IsPtr is much more specific than IsInHeap.  This routine returns
  3680.           the carry flag clear if and only if es:di contains the address
  3681.           of a properly allocated (and currently allocated) block on the
  3682.           heap.  This pointer must be a value returned by Malloc, Realloc,
  3683.           or DupPtr and that block must be currently allocated for IsPtr
  3684.           to return the carry flag clear.
  3685.  
  3686.  
  3687. Include:                stdlib.a
  3688.  
  3689.  
  3690. Character Set Routines
  3691. ----------------------
  3692.  
  3693. The character set routines let you deal with groups of characters as a set
  3694. rather than a string.  A set is an unordered collection of objects where
  3695. membership (presence or absence) is the only important quality.  The stdlib
  3696. set routines were designed to let you quickly check if an ASCII character is
  3697. in a set, to quickly add characters to a set or remove characters from a set.
  3698. These operations are the ones most commonly used on character sets.  The
  3699. other operations (like union, intersection, difference, etc.) are useful, but
  3700. are not as popular as the former routines.  Therefore, the data structure
  3701. has been optimized for sets to handle the membership and add/delete operations
  3702. at the slight expense of the others.
  3703.  
  3704. Character sets are implemented via bit vectors.  A "1" bit means that an item
  3705. is present in the set and a "0" bit means that the item is absent from the
  3706. set.  The most common implementation of a character set is to use thirty-two 
  3707. consecutive bytes, eight bytes per, giving 256 bits (one bit for each char-
  3708. acter in the character set).  While this makes certain operations (like 
  3709. assignment, union, intersection, etc.) fast and convenient, other operations
  3710. (membership, add/remove items) run much slower.  Since these are the more 
  3711. important operations, a different data structure is used to represent sets.  
  3712. A faster approach is to simply use a byte value for each item in the set.  
  3713. This offers a major advantage over the thirty-two bit scheme:  for operations 
  3714. like membership it is very fast (since all you have got to do is index into 
  3715. an array and test the resulting value).  It has two drawbacks:  first, oper-
  3716. ations like set assignment, union, difference, etc., require 256 operations 
  3717. rather than thirty-two; second, it takes eight times as much memory.
  3718.  
  3719. The first drawback, speed, is of little consequence.  You will rarely use the
  3720. the operations so affected, so the fact that they run a little slower will be
  3721. of little consequence.  Wasting 224 bytes is a problem, however.  Especially
  3722. if you have a lot of character sets.
  3723.  
  3724. The approach used here is to allocate 272 bytes.  The first eight bytes con-
  3725. tain bit masks, 1, 2, 4, 8, 16, 32, 64, 128.  These masks tell you which bit
  3726. in the following 264 bytes is associated with the set.  This facilitates 
  3727. putting eight sets into 272 bytes (34 bytes per character set).  This provides
  3728. almost the speed of the 256-byte set with only a two byte overhead.  In the
  3729. stdlib.a file there is a macro that lets you define a group of character
  3730. sets:  set.  The macro is used as follows:
  3731.  
  3732.     set set1, set2, set3, ... , set8
  3733.  
  3734. You must supply between one and eight labels in the operand field.  These are
  3735. the names of the sets you want to create.  The set macro automatically 
  3736. attaches these labels to the appropriate mask bytes in the set.  The actual
  3737. bit patterns for the set begin eight bytes later (from each label).  There-
  3738. fore, the byte corresponding to chr(0) is staggered by one byte for each
  3739. set (which explains the other eight bytes needed above and beyond the 256 
  3740. required for the set).  When using the set manipulation routines, you should
  3741. always pass the address of the mask byte (i.e., the seg/offset of one of the 
  3742. labels above) to the particular set manipulation routine you are using. 
  3743. Passing the address of the structure created with the macro above will 
  3744. reference only the first set in the group.
  3745.  
  3746. Note that you can use the set operations for fast pattern matching appli-
  3747. cations.  The set membership operation for example, is much faster that the 
  3748. strspan routine found in the string package.  Proper use of character sets
  3749. can produce a program which runs much faster than some of the equivalent
  3750. string operations.
  3751.  
  3752.  
  3753. Routine:  Createsets
  3754. --------------------
  3755.  
  3756. Category:             Character Set Routine
  3757.  
  3758. Registers on Entry:   no parameters passed
  3759.  
  3760. Registers on return:  ES:DI - pointer to eight sets
  3761.  
  3762. Flags affected:       Carry = 0 if no error. Carry = 1 if insufficient
  3763.               memory to allocate storage for sets.
  3764.  
  3765. Example of Usage:
  3766.               Createsets
  3767.               jc      NoMemory
  3768.               mov     word ptr SetPtr,   di
  3769.               mov     word ptr SetPtr+2, es
  3770.  
  3771. Description:  Createsets allocates 272 bytes on the heap.   This is sufficient
  3772.           room for eight character sets.  It then initializes the first
  3773.           eight bytes of this storage with the proper mask values for
  3774.           each set.  Location es:0[di] gets set to 1, location es:1[di]
  3775.           gets 2, location es:2[di] gets 4, etc.  The Createsets routine
  3776.           also initializes all of the sets to the empty set by clearing
  3777.           all the bits to zero.
  3778.  
  3779. Include:              stdlib.a
  3780.  
  3781.  
  3782. Routine:  EmptySet
  3783. ------------------
  3784.  
  3785. Category:             Character Set Routine
  3786.  
  3787. Registers on Entry:   ES:DI - pointer to first byte of desired set
  3788.  
  3789. Registers on return:  None
  3790.  
  3791. Flags affected:          None
  3792.  
  3793. Example of Usage:
  3794.               les     di,  SetPtr
  3795.               add     di,  3          ; Point at 4th set in group.
  3796.               Emptyset
  3797.  
  3798.  
  3799. Description:  Emptyset clears out the bits in a character set to zero
  3800.           (thereby setting it to the empty set).  Upon entry, es:di must
  3801.           point at the first byte of the character set you want to clear.
  3802.           Note that this is not the address returned by Createsets.  The
  3803.           first eight bytes of a character set structure are the
  3804.           addresses of eight different sets.  ES:DI must point at one of
  3805.           these bytes upon entry into Emptyset.
  3806.  
  3807. Include:              stdlib.a
  3808.  
  3809.  
  3810. Routine:  Rangeset
  3811. ------------------
  3812.  
  3813. Category:             Character Set Routine
  3814.  
  3815. Registers on entry:   ES:DI (contains the address of the first byte of the set)
  3816.               AL    (contains the lower bound of the items)
  3817.               AH    (contains the upper bound of the items)
  3818.  
  3819. Registers on return:  None
  3820.  
  3821. Flags affected:       None
  3822.  
  3823. Example of Usage:
  3824.               lea di, SetPtr
  3825.               add di, 4
  3826.               mov al, 'A'
  3827.               mov ah, 'Z'
  3828.               rangeset
  3829.  
  3830.  
  3831. Description:  This routine adds a range of values to a set with ES:DI as the
  3832.           pointer to the set, AL as the lower bound of the set, and
  3833.           AH as the upper bound of the set (AH has to be greater than
  3834.           AL, otherwise, there will an error).
  3835.  
  3836. Include:              stdlib.a
  3837.  
  3838.  
  3839. Routine:  Addstr (l)
  3840. --------------------
  3841.  
  3842. Category:             Character Set Routine
  3843.  
  3844. Registers on Entry:   ES:DI- pointer to first byte of desired set
  3845.               DX:SI- pointer to string to add to set (Addstr only)
  3846.               CS:RET-pointer to string to add to set (Addstrl only)
  3847.  
  3848. Registers on Return:  None
  3849.  
  3850. Flags Affected:       None
  3851.  
  3852. Example of Usage:
  3853.               les     di, SetPtr
  3854.               add     di, 1           ;Point at 2nd set in group.
  3855.               mov     dx, seg CharStr ;Pointer to string
  3856.               lea     si, CharStr     ; chars to add to set.
  3857.               addstr                  ;Union in these characters.
  3858. ;
  3859.               les     di, SetPtr      ;Point at first set in group.
  3860.               addstrl
  3861.               db      "AaBbCcDdEeFf0123456789",0
  3862. ;
  3863.  
  3864.  
  3865. Description:  Addstr lets you add a group of characters to a set by
  3866.           specifying a string containing the characters you want in
  3867.           the set.  To Addstr you pass a pointer to a zero-terminated
  3868.           string in dx:si.  Addstr will add (union) each character
  3869.           from this string into the set.
  3870.  
  3871.           Addstrl works the same way except you pass the string as
  3872.           a literal string constant in the code stream rather than
  3873.           via ES:DI.
  3874.  
  3875. Include:              stdlib.a
  3876.  
  3877.  
  3878. Routine:  Rmvstr (l)
  3879. --------------------
  3880.  
  3881.  
  3882. Category:             Character Set Routine
  3883.  
  3884.  
  3885. Registers on entry:   ES:DI contains the address of first byte of a set
  3886.               DX:SI contains the address of string to be removed
  3887.                  from a set (Rmvstr only)
  3888.               CS:RET pointer to string to add to set (Rmvstrl only)
  3889.  
  3890.  
  3891. Registers on return:  None
  3892.  
  3893.  
  3894. Flags affected:       None
  3895.  
  3896.  
  3897. Example of Usage:
  3898.               les     di, SetPtr
  3899.               mov     dx, seg CharStr
  3900.               lea     si, CharStr
  3901.               rmvstr
  3902.  
  3903.               mov     dx, seg CharStr
  3904.               lea     si, CharStr
  3905.               rmvstrl
  3906.               db          "ABCDEFG",0
  3907.  
  3908.  
  3909. Description:  This routine is to remove a string from a set with ES:DI
  3910.           pointing to its first byte, and DX:SI pointing to the
  3911.           string to be removed from the set.
  3912.  
  3913.           For Rmvstrl, the string of characters to remove from the
  3914.           set follows the call in the code stream.
  3915.  
  3916. Include:              stdlib.a
  3917.  
  3918.  
  3919. Routine:  AddChar
  3920. -----------------
  3921.  
  3922. Category:             Character Set Routine
  3923.  
  3924. Registers on Entry:   ES:DI- pointer to first byte of desired set
  3925.               AL- character to add to the set
  3926.  
  3927. Registers on Return:  None
  3928.  
  3929. Flags affected:       None
  3930.  
  3931. Example of Usage:
  3932.               les     di, SetPtr
  3933.               add     di, 1           ;Point at 2nd set in group.
  3934.               mov     al, Ch2Add      ;Character to add to set.
  3935.               addchar
  3936.  
  3937.  
  3938. Description:  AddChar lets you add a single character (passed in AL)
  3939.           to a set.
  3940.  
  3941. Include:              stdlib.a
  3942.  
  3943.  
  3944. Routine:  Rmvchar
  3945. -----------------
  3946.  
  3947. Category:             Character Set Routine
  3948.  
  3949. Registers on entry:   ES:DI (contains the address of first byte of a set)
  3950.               AL    (contains the character to be removed)
  3951.  
  3952. Registers on return:  None
  3953.  
  3954. Flags affected:          None
  3955.  
  3956. Example of Usage:
  3957.               lea di, SetPtr
  3958.               add di, 7        ;Point at eighth set in group.
  3959.               mov al, Ch2Rmv
  3960.               Rmvchar
  3961.  
  3962. Description:  This routine removes the character in AL from a set.
  3963.           ES:SI points to the set's mask byte. The corresponding
  3964.           bit in the set is cleared to zero.
  3965.  
  3966. Include:              stdlib.a
  3967.  
  3968.  
  3969. Routine:  Member
  3970. ----------------
  3971.  
  3972. Category:             Character Set Routine
  3973.  
  3974. Registers on entry:   ES:DI (contains the address of first byte of a set)
  3975.               AL    (contains the character to be compared)
  3976.  
  3977. Registers on return:  None
  3978.  
  3979. Flags affected:       Zero flag (Zero = 1 if the character is in the set
  3980.                  Zero = 0 if the character is not in the set)
  3981.  
  3982. Example of Usage:
  3983.               les di, SetPtr
  3984.               add di, 1
  3985.               mov al, 'H'
  3986.               member
  3987.               je IsInSet
  3988.  
  3989.  
  3990. Description:  Member is used to find out if the character in AL is in a set
  3991.           with ES:DI pointing to its mask byte. If the character is in
  3992.           the set, the zero flag is set to 1. If not, the zero flag is
  3993.           set to zero.
  3994.  
  3995. Include:              stdlib.a
  3996.  
  3997.  
  3998. Routine:  CopySet
  3999. -----------------
  4000.  
  4001. Category:            Character Set Routine
  4002.  
  4003. Register on entry:   ES:DI- pointer to first byte of destination set.
  4004.              DX:SI- pointer to first byte of source set.
  4005.  
  4006. Register on Return:  None
  4007.  
  4008. Flags affected:      None
  4009.  
  4010. Example of Usage:
  4011.              les     di, SetPtr
  4012.              add     di, 7           ;Point at 8th set in group.
  4013.              mov     dx, seg SetPtr2 ;Point at first set in group.
  4014.              lea     si, SetPtr2
  4015.              copyset
  4016.  
  4017.  
  4018. Description:  CopySet copies the items from one set to another.  This is a
  4019.           straight assignment, not a union operation.  After the
  4020.           operation, the destination set is identical to the source set,
  4021.           both in terms of the element present in the set and absent
  4022.           from the set.
  4023.  
  4024.  
  4025. Include:             stdlib.a
  4026.  
  4027.  
  4028. Routine:  SetUnion
  4029. ------------------
  4030.  
  4031. Category:            Character Set Routine
  4032.  
  4033. Register on entry:   ES:DI - pointer to first byte of destination set.
  4034.              DX:SI - pointer to first byte of source set.
  4035.  
  4036. Register on return:  None
  4037.  
  4038. Flags affected:      None
  4039.  
  4040. Example of Usage:    les   di, SetPtr
  4041.              add   di, 7              ;point at 8th set in group.
  4042.              mov   dx, seg SetPtr2    ;point at 1st set in group.
  4043.              lea   si, sSetPtr2
  4044.              unionset
  4045.  
  4046.  
  4047. Description:  The SetUnion routine computes the union of two sets.
  4048.           That is, it adds all of the items present in a source set
  4049.           to a destination set.  This operation preserves items
  4050.           present in the destination set before the SetUnion
  4051.           operation.
  4052.  
  4053. Include:             stdlib.a
  4054.  
  4055.  
  4056. Routine:  SetIntersect
  4057. ----------------------
  4058.  
  4059. Category:            Character Set Routine
  4060.  
  4061. Register on entry:   ES:DI - pointer to first byte of destination set.
  4062.              DX:SI - pointer to first byte of source set.
  4063.  
  4064. Register on return:  None
  4065.  
  4066. Flags affected:      None
  4067.  
  4068. Example of Usage:
  4069.              les   di, SetPtr
  4070.              add   di, 7              ;point at 8th set in group.
  4071.              mov   dx, seg SetPtr2    ;point at 1st set in group.
  4072.              lea   si, SetPtr2
  4073.              setintersect
  4074.  
  4075. Description:  SetIntersect computes the intersection of two sets, leaving
  4076.           the result in the destination set.  The new set consists
  4077.           only of those items which previously appeared in
  4078.           both the source and destination sets.
  4079.  
  4080. Include:             stdlib.a
  4081.  
  4082.  
  4083. Routine:  SetDifference
  4084. -----------------------
  4085.  
  4086. Category:            Character Set Routine
  4087.  
  4088. Register on entry:   ES:DI - pointer to the first byte of destination set.
  4089.              DX:SI - pointer to the first byte of the source set.
  4090.  
  4091. Register on return:  None
  4092.  
  4093. Flags affected:      None
  4094.  
  4095. Example of Usage:
  4096.              les   di, SetPtr
  4097.              add   di, 7               ;point at 8th set in group.
  4098.              mov   dx, seg SetPtr2     ;point at 1st set in group.
  4099.              lea   si, SetPtr2
  4100.              setdifference
  4101.  
  4102.  
  4103. Description:  SetDifference computes the result of (ES:DI) := (ES:DI) -
  4104.           (DX:SI).  The destination set is left with its original
  4105.           items minus those items which are also in the source set.
  4106.  
  4107. Include:             stdlib.a
  4108.  
  4109.  
  4110. Routine:  Nextitem
  4111. ------------------
  4112.  
  4113. Category:             Character Set Routine
  4114.  
  4115. Registers on entry:   ES:DI (contains the address of first byte of the set)
  4116.  
  4117. Registers on return:  AL (contains the first item in the set)
  4118.  
  4119. Flags affected:       None
  4120.  
  4121. Example of Usage:
  4122.               les di, SetPtr
  4123.               add di, 7        ;Point at eighth set in group.
  4124.               nextitem
  4125.  
  4126.  
  4127. Description:  Nextitem is the routine to search the first character (item)
  4128.           in the set with ES:DI pointing to its mask byte. AL will
  4129.           return the character in the set. If the set is empty, AL
  4130.           will contain zero.
  4131.  
  4132. Include:              stdlib.a
  4133.  
  4134.  
  4135. Routine:  Rmvitem
  4136. -----------------
  4137.  
  4138. Category:             Character Set Routine
  4139.  
  4140. Registers on entry:   ES:DI (contains the address fo first byte of the set)
  4141.  
  4142. Registers on return:  AL (contains the first item in the set)
  4143.  
  4144. Flags affected:       None
  4145.  
  4146. Example of Usage:
  4147.               les di, SetPtr
  4148.               add di, 7
  4149.               rmvitem
  4150.  
  4151. Description:  Rmvitem locates the first available item in the set and
  4152.           removes it with ES:DI pointing to its mask byte. AL will
  4153.           return the item removed. If the set is empty, AL will
  4154.           return zero.
  4155.  
  4156. Include:              stdlib.a
  4157.  
  4158.  
  4159.  
  4160. Floating Point Routines
  4161. -----------------------
  4162.  
  4163. The floating point routines provide a basic floating point package for
  4164. 80x86 assembly language users.  The floating point package deals with
  4165. four different floating point formats: IEEE 32-bit, 64-bit, and 80-bit
  4166. formats, and an internal 81-bit format.  The external formats mostly
  4167. support the IEEE standard except for certain esoteric values such as
  4168. denormalized numbers, NaNs, infinities, and other such cases.
  4169.  
  4170. The package provides two "pseudo-registers", a floating point accumulator
  4171. and a floating point operand.  It provides routines to load and store these
  4172. pseudo-registers from memory operands (using the various formats) and then
  4173. all other operations apply to these two operands.  All computations use the
  4174. internal 81-bit floating point format.  The package automatically converts
  4175. between the internal format and the external format when loading and storing
  4176. values.
  4177.  
  4178. Do not write code which assumes the internal format is 81 bits.  This format
  4179. will change in the near future when I get a chance to add guard bits to
  4180. all the computations.  If your code assumes 81 bits, it will break at that
  4181. point.  Besides, there is no reason your code should count on the size of
  4182. the internal operations anyway.  Stick with the IEEE formats and you'll
  4183. be much better off (since your code can be easily upgraded to deal with
  4184. numeric coprocessors).
  4185.  
  4186. WARNING: These routines have not been sufficiently tested as of 10/10/91.
  4187. Use them with care.  Report any problems with these routines to Randy Hyde
  4188. via the electronic addresses provided in this document or by sending a
  4189. written report to UC Riverside.  As I get more time, I will further test
  4190. these routines and add additional functions to the package.
  4191.  
  4192.                     *** Randy Hyde
  4193.  
  4194.  
  4195.  
  4196. Routine:  lsfpa
  4197. ---------------
  4198.  
  4199. Category:             Floating point Routine
  4200.  
  4201. Registers on entry:   ES:DI points at a single precision (32-bit) value to load
  4202.  
  4203. Registers on return:  None
  4204.  
  4205. Flags affected:       None
  4206.  
  4207. Example of Usage:
  4208.             les di, FPValue
  4209.             lsfpa
  4210.  
  4211. Description:    LSFPA loads a single precision floating point value into the
  4212.         internal floating point accumulator.  It also converts the
  4213.         32-bit format to the internal 81-bit format used by the
  4214.         floating point package.
  4215.  
  4216. Include:    stdlib.a
  4217.  
  4218. Routine:  ssfpa
  4219. ---------------
  4220.  
  4221. Category:             Floating point Routine
  4222.  
  4223. Registers on entry:   ES:DI points at a single precision (32-bit) value where
  4224.               this routine should store the floating point acc.
  4225.  
  4226. Registers on return:  None
  4227.  
  4228. Flags affected:       Carry set if conversion error.
  4229.  
  4230. Example of Usage:
  4231.             les di, FPValue
  4232.             ssfpa
  4233.  
  4234. Description:    SSFPA stores the floating point accumulator into a single
  4235.         precision variable in memory (pointed at by ES:DI).  It
  4236.         converts the value from the 81-bit format to the 32-bit
  4237.         value before storing the result.   The 64-bit mantissa used
  4238.         by the FP package is rounded to 24 bits during the store.
  4239.         The exponent could be out of range.  If this occurs, SSFPA
  4240.         returns with the carry flag set.
  4241.  
  4242. Include:    stdlib.a
  4243.  
  4244.  
  4245. Routine:  ldfpa
  4246. ---------------
  4247.  
  4248. Category:             Floating point Routine
  4249.  
  4250. Registers on entry:   ES:DI points at a double precision (64-bit) value to load
  4251.  
  4252. Registers on return:  None
  4253.  
  4254. Flags affected:       None
  4255.  
  4256. Example of Usage:
  4257.             les di, FPValue
  4258.             ldfpa
  4259.  
  4260. Description:    LDFPA loads a double precision floating point value into the
  4261.         internal floating point accumulator.  It also converts the
  4262.         64-bit format to the internal 81-bit format used by the
  4263.         floating point package.
  4264.  
  4265. Include:    stdlib.a
  4266.  
  4267. Routine:  sdfpa
  4268. ---------------
  4269.  
  4270. Category:             Floating point Routine
  4271.  
  4272. Registers on entry:   ES:DI points at a double precision (64-bit) value where
  4273.               this routine should store the floating point acc.
  4274.  
  4275. Registers on return:  None
  4276.  
  4277. Flags affected:       Carry set if conversion error.
  4278.  
  4279. Example of Usage:
  4280.             les di, FPValue
  4281.             sdfpa
  4282.  
  4283. Description:    SDFPA stores the floating point accumulator into a double
  4284.         precision variable in memory (pointed at by ES:DI).  It
  4285.         converts the value from the 81-bit format to the 64-bit
  4286.         value before storing the result.   The 64-bit mantissa used
  4287.         by the FP package is rounded to 51 bits during the store.
  4288.         The exponent could be out of range.  If this occurs, SDFPA
  4289.         returns with the carry flag set.
  4290.  
  4291. Include:    stdlib.a
  4292.  
  4293.  
  4294. Routine:  lefpa
  4295. ---------------
  4296.  
  4297. Category:             Floating point Routine
  4298.  
  4299. Registers on entry:   ES:DI points at an extended precision (80-bit) value to
  4300.               load
  4301.  
  4302. Registers on return:  None
  4303.  
  4304. Flags affected:       None
  4305.  
  4306. Example of Usage:
  4307.             les di, FPValue
  4308.             lefpa
  4309.  
  4310. Description:    LEFPA loads an extended precision floating point value into
  4311.         the internal floating point accumulator.  It also converts the
  4312.         80-bit format to the internal 81-bit format used by the
  4313.         floating point package.
  4314.  
  4315. Include:    stdlib.a
  4316.  
  4317.  
  4318. Routine:  lefpal
  4319. ----------------
  4320.  
  4321. Category:             Floating point Routine
  4322.  
  4323. Registers on entry:   CS:RET points at an extended precision (80-bit) value to
  4324.               load
  4325.  
  4326. Registers on return:  None
  4327.  
  4328. Flags affected:       None
  4329.  
  4330. Example of Usage:
  4331.             lefpal
  4332.             dt    1.345e-3
  4333.  
  4334. Description:    LEFPAL loads an extended precision floating point value into
  4335.         the internal floating point accumulator.  It also converts the
  4336.         80-bit format to the internal 81-bit format used by the
  4337.         floating point package.
  4338.  
  4339.         Unlike LEFPA, LEFPAL gets its operand directly from the code
  4340.         stream.  You must follow the call to lefpal with a ten-byte
  4341.         (80-bit) floating point constant.
  4342. Include:    stdlib.a
  4343.  
  4344. Routine:  sefpa
  4345. ---------------
  4346.  
  4347. Category:             Floating point Routine
  4348.  
  4349. Registers on entry:   ES:DI points at an extended precision (80-bit) value
  4350.               where this routine should store the floating point acc.
  4351.  
  4352. Registers on return:  None
  4353.  
  4354. Flags affected:       Carry set if conversion error.
  4355.  
  4356. Example of Usage:
  4357.             les di, FPValue
  4358.             sefpa
  4359.  
  4360. Description:    SEFPA stores the floating point accumulator into an extended
  4361.         precision variable in memory (pointed at by ES:DI).  It
  4362.         converts the value from the 81-bit format to the 80-bit
  4363.         value before storing the result.
  4364.  
  4365.         The exponent could be out of range.  If this occurs, SEFPA
  4366.         returns with the carry flag set.
  4367.  
  4368. Include:    stdlib.a
  4369.  
  4370.  
  4371. Routine:  lsfpo
  4372. ---------------
  4373.  
  4374. Category:             Floating point Routine
  4375.  
  4376. Registers on entry:   ES:DI points at a single precision (32-bit) value to load
  4377.  
  4378. Registers on return:  None
  4379.  
  4380. Flags affected:       None
  4381.  
  4382. Example of Usage:
  4383.             les di, FPValue
  4384.             lsfpo
  4385.  
  4386. Description:    LSFPA loads a single precision floating point value into the
  4387.         internal floating point operand.  It also converts the
  4388.         32-bit format to the internal 81-bit format used by the
  4389.         floating point package.
  4390.  
  4391. Include:    stdlib.a
  4392.  
  4393.  
  4394. Routine:  ldfpo
  4395. ---------------
  4396.  
  4397. Category:             Floating point Routine
  4398.  
  4399. Registers on entry:   ES:DI points at a double precision (64-bit) value to load
  4400.  
  4401. Registers on return:  None
  4402.  
  4403. Flags affected:       None
  4404.  
  4405. Example of Usage:
  4406.             les di, FPValue
  4407.             ldfpo
  4408.  
  4409. Description:    LDFPO loads a double precision floating point value into the
  4410.         internal floating point operand.  It also converts the
  4411.         64-bit format to the internal 81-bit format used by the
  4412.         floating point package.
  4413.  
  4414. Include:    stdlib.a
  4415.  
  4416.  
  4417. Routine:  lefpo
  4418. ---------------
  4419.  
  4420. Category:             Floating point Routine
  4421.  
  4422. Registers on entry:   ES:DI points at an extended precision (80-bit) value to
  4423.               load
  4424.  
  4425. Registers on return:  None
  4426.  
  4427. Flags affected:       None
  4428.  
  4429. Example of Usage:
  4430.             les di, FPValue
  4431.             lefpo
  4432.  
  4433. Description:    LEFPO loads an extended precision floating point value into
  4434.         the internal floating point operand.  It also converts the
  4435.         80-bit format to the internal 81-bit format used by the
  4436.         floating point package.
  4437.  
  4438. Include:    stdlib.a
  4439.  
  4440.  
  4441. Routine:  lefpol
  4442. ----------------
  4443.  
  4444. Category:             Floating point Routine
  4445.  
  4446. Registers on entry:   CS:RET points at an extended precision (80-bit) value to
  4447.               load
  4448.  
  4449. Registers on return:  None
  4450.  
  4451. Flags affected:       None
  4452.  
  4453. Example of Usage:
  4454.             lefpal
  4455.             dt    1.345e-3
  4456.  
  4457. Description:    LEFPOL loads an extended precision floating point value into
  4458.         the internal floating point operand.  It also converts the
  4459.         80-bit format to the internal 81-bit format used by the
  4460.         floating point package.
  4461.  
  4462.         Unlike LEFPO, LEFPOL gets its operand directly from the code
  4463.         stream.  You must follow the call to lefpal with a ten-byte
  4464.         (80-bit) floating point constant.
  4465. Include:    stdlib.a
  4466.  
  4467.  
  4468. Routine:  itof
  4469. --------------
  4470.  
  4471. Category:             Floating point Routine
  4472.  
  4473. Registers on entry:   AX contains a signed integer value
  4474.  
  4475. Registers on return:  None
  4476.  
  4477. Flags affected:       None
  4478.  
  4479. Example of Usage:
  4480.             mov    ax, -1234
  4481.             itof
  4482.  
  4483. Description:    ITOF converts the 16-bit signed integer in AX to a floating
  4484.         point value, storing the result in the floating point
  4485.         accumuator.
  4486.  
  4487. Include:    stdlib.a
  4488.  
  4489.  
  4490. Routine:  utof
  4491. --------------
  4492.  
  4493. Category:             Floating point Routine
  4494.  
  4495. Registers on entry:   AX contains an unsigned integer value
  4496.  
  4497. Registers on return:  None
  4498.  
  4499. Flags affected:       None
  4500.  
  4501. Example of Usage:
  4502.             mov    ax, -1234
  4503.             itof
  4504.  
  4505. Description:    UTOF converts the 16-bit unsigned integer in AX to a floating
  4506.         point value, storing the result in the floating point
  4507.         accumuator.
  4508.  
  4509. Include:    stdlib.a
  4510.  
  4511.  
  4512. Routine:  ultof
  4513. ---------------
  4514.  
  4515. Category:             Floating point Routine
  4516.  
  4517. Registers on entry:   DX:AX contains an unsigned 32-bit integer value
  4518.  
  4519. Registers on return:  None
  4520.  
  4521. Flags affected:       None
  4522.  
  4523. Example of Usage:
  4524.             mov    dx, word ptr val32+2
  4525.             mov    ax, word ptr val32
  4526.             ultof
  4527.  
  4528. Description:    ULTOF converts the 32-bit unsigned integer in DX:AX to a
  4529.         floating point value, storing the result in the floating
  4530.         point accumuator.
  4531.  
  4532. Include:    stdlib.a
  4533.  
  4534.  
  4535. Routine:  ltof
  4536. --------------
  4537.  
  4538. Category:             Floating point Routine
  4539.  
  4540. Registers on entry:   DX:AX contains a signed 32-bit integer value
  4541.  
  4542. Registers on return:  None
  4543.  
  4544. Flags affected:       None
  4545.  
  4546. Example of Usage:
  4547.             mov    dx, word ptr val32+2
  4548.             mov    ax, word ptr val32
  4549.             ltof
  4550.  
  4551. Description:    LTOF converts the 32-bit signed integer in DX:AX to a
  4552.         floating point value, storing the result in the floating
  4553.         point accumuator.
  4554.  
  4555. Include:    stdlib.a
  4556.  
  4557.  
  4558. Routine:  ftoi
  4559. --------------
  4560.  
  4561. Category:             Floating point Routine
  4562.  
  4563. Registers on entry:   None
  4564.  
  4565. Registers on return:  AX contains 16-bit signed integer
  4566.  
  4567. Flags affected:       Carry is set if conversion error occurs.
  4568.  
  4569. Example of Usage:
  4570.             ftoi
  4571.             puti        ;Print AX as integer value
  4572.  
  4573.  
  4574. Description:    FTOI converts the floating point accumulator value to a
  4575.         16-bit signed integer and returns the result in AX.  If
  4576.         the floating point number will not fit in AX, FTOI returns
  4577.         with the carry flag set.
  4578.  
  4579. Include:    stdlib.a
  4580.  
  4581.  
  4582. Routine:  ftou
  4583. --------------
  4584.  
  4585. Category:             Floating point Routine
  4586.  
  4587. Registers on entry:   None
  4588.  
  4589. Registers on return:  AX contains 16-bit unsigned integer
  4590.  
  4591. Flags affected:       Carry is set if conversion error occurs.
  4592.  
  4593. Example of Usage:
  4594.             ftou
  4595.             putu        ;Print AX as an unsigned value
  4596.  
  4597.  
  4598. Description:    FTOU converts the floating point accumulator value to a
  4599.         16-bit unsigned integer and returns the result in AX.  If
  4600.         the floating point number will not fit in AX, FTOU returns
  4601.         with the carry flag set.
  4602.  
  4603. Include:    stdlib.a
  4604.  
  4605.  
  4606. Routine:  ftol
  4607. --------------
  4608.  
  4609. Category:             Floating point Routine
  4610.  
  4611. Registers on entry:   None
  4612.  
  4613. Registers on return:  DX:AX contains a 32-bit signed integer
  4614.  
  4615. Flags affected:       Carry is set if conversion error occurs.
  4616.  
  4617. Example of Usage:
  4618.             ftol
  4619.             putl        ;Print DX:AX as integer value
  4620.  
  4621.  
  4622. Description:    FTOL converts the floating point accumulator value to a
  4623.         32-bit signed integer and returns the result in DX:AX.  If
  4624.         the floating point number will not fit in DX:AX, FTOL returns
  4625.         with the carry flag set.
  4626.  
  4627. Include:    stdlib.a
  4628.  
  4629.  
  4630. Routine:  ftoul
  4631. ---------------
  4632.  
  4633. Category:             Floating point Routine
  4634.  
  4635. Registers on entry:   None
  4636.  
  4637. Registers on return:  DX:AX contains a 32-bit unsigned integer
  4638.  
  4639. Flags affected:       Carry is set if conversion error occurs.
  4640.  
  4641. Example of Usage:
  4642.             ftoul
  4643.             putul        ;Print DX:AX as an integer value
  4644.  
  4645.  
  4646. Description:    FTOUL converts the floating point accumulator value to a
  4647.         32-bit unsigned integer and returns the result in DX:AX.  If
  4648.         the floating point number will not fit in DX:AX, FTOUL returns
  4649.         with the carry flag set.
  4650.  
  4651. Include:    stdlib.a
  4652.  
  4653.  
  4654. Routine:  fpadd
  4655. ---------------
  4656.  
  4657. Category:             Floating point Routine
  4658.  
  4659. Registers on entry:   None
  4660.  
  4661. Registers on return:  None
  4662.  
  4663. Flags affected:       None
  4664.  
  4665. Example of Usage:
  4666.             fpadd
  4667.  
  4668. Description:    FPADD adds the floating point operand to the floating point
  4669.         accumulator leaving the result in the floating point
  4670.         accumulator.
  4671.  
  4672. Include:    stdlib.a
  4673.  
  4674.  
  4675. Routine:  fpsub
  4676. ---------------
  4677.  
  4678. Category:             Floating point Routine
  4679.  
  4680. Registers on entry:   None
  4681.  
  4682. Registers on return:  None
  4683.  
  4684. Flags affected:       None
  4685.  
  4686. Example of Usage:
  4687.             fpsub
  4688.  
  4689. Description:    FPSUB subtracts the floating point operand from the floating
  4690.         point accumulator leaving the result in the floating point
  4691.         accumulator.
  4692.  
  4693. Include:    stdlib.a
  4694.  
  4695.  
  4696. Routine:  fpcmp
  4697. ---------------
  4698.  
  4699. Category:             Floating point Routine
  4700.  
  4701. Registers on entry:   None
  4702.  
  4703. Registers on return:  AX contains result of comparison.
  4704.  
  4705. Flags affected:       As appropriate for a comparison.  You can use the
  4706.               conditional branches to check the comparison after
  4707.               calling this routine.  Be sure to use the *signed*
  4708.               conditional jumps (e.g., JG, JGE, etc.).
  4709.  
  4710. Example of Usage:
  4711.             fpcmp
  4712.             jge    FPACCgeFPOP
  4713.  
  4714. Description:    FPCMP compares the floating point accumulator to the
  4715.         floating point operand and sets the flags according to the
  4716.         result of the comparison.  It also returns a value in AX
  4717.         as follows:
  4718.  
  4719.             AX    Result
  4720.             -1    FPACC < FPOP
  4721.              0    FPACC = FPOP
  4722.              1    FPACC > FPOP
  4723.  
  4724. Include:    stdlib.a
  4725.  
  4726.  
  4727. Routine:  fpmul
  4728. --------------
  4729.  
  4730. Category:             Floating point Routine
  4731.  
  4732. Registers on entry:   None
  4733.  
  4734. Registers on return:  None
  4735.  
  4736. Flags affected:       None
  4737.  
  4738. Example of Usage:
  4739.             fpmul
  4740.  
  4741. Description:    FPMUL multiplies the floating point accumulator by the floating
  4742.         point operand and leaves the result in the floating point
  4743.         accumulator.
  4744.  
  4745. Include:    stdlib.a
  4746.  
  4747.  
  4748. Routine:  fpdiv
  4749. ---------------
  4750.  
  4751. Category:             Floating point Routine
  4752.  
  4753. Registers on entry:   None
  4754.  
  4755. Registers on return:  None
  4756.  
  4757. Flags affected:       None
  4758.  
  4759. Example of Usage:
  4760.             fpdiv
  4761.  
  4762. Description:    FPDIV divides the floating point accumulator by the floating
  4763.         point operand and leaves the result in the floating point
  4764.         accumulator.
  4765.  
  4766. Include:    stdlib.a
  4767.  
  4768.  
  4769. Routine:  ftoa (2,m)
  4770. --------------------
  4771.  
  4772. Category:             Floating point Routine
  4773.  
  4774. Registers on entry:   ES:DI points at buffer to hold result (ftoa/ftoa2 only)
  4775.               AL- Field width for floating point value.
  4776.               AH- Number of positions to the right of the dec pt.
  4777.  
  4778. Registers on return:  ES:DI points at beginning of string (ftoa/ftoam only)
  4779.               ES:DI points at zero terminating byte (ftoa2 only)
  4780.  
  4781. Flags affected:       Carry is set if malloc error (ftoam only)
  4782.  
  4783. Example of Usage:
  4784.             mov    di, seg buffer
  4785.             mov    es, di
  4786.             lea    di, buffer
  4787.             mov    ah, 2        ;Two digits after "."
  4788.             mov    al, 10        ;Use a total of ten positions
  4789.             ftoa
  4790.  
  4791.  
  4792.  
  4793. Description:    FTOA (2,M) converts the value in the floating point accumulator
  4794.         to a string of characters which represent that value.  These
  4795.         routines use a decimal representation.  The value in AH is
  4796.         the number of digits to put after the decimal point, AL
  4797.         contains the total field width (including room for the sign
  4798.         and decimal point).  The field width specification works
  4799.         just like Pascal or FORTRAN.  If the number will not fit in
  4800.         the specified field width, FTOA outputs a bunch of "#"
  4801.         characters.
  4802.  
  4803.         FTOA stores the converted string at the address specified by
  4804.         ES:DI upon entry.  There must be at least AL+1 bytes at this
  4805.         address.  It returns with ES:DI pointing at the start of this
  4806.         buffer.
  4807.  
  4808.         FTOA2 works just like FTOA except it does not preserve DI.
  4809.         It returns with DI pointing at the zero terminating byte.
  4810.  
  4811.         FTOAM allocates storage for the string on the heap and returns
  4812.         a pointer to the converted string in ES:DI.
  4813.  
  4814.         Note: this routine preserves the value in the floating point
  4815.         accumulator but it wipes out the value in the floating point
  4816.         operand.
  4817.  
  4818. Include:    stdlib.a
  4819.  
  4820.  
  4821. Routine:  etoa (2,m)
  4822. --------------------
  4823.  
  4824. Category:             Floating point Routine
  4825.  
  4826. Registers on entry:   ES:DI points at buffer to hold result (etoa/etoa2 only)
  4827.               AL- Field width for floating point value.
  4828.  
  4829. Registers on return:  ES:DI points at beginning of string (etoa/etoam only)
  4830.               ES:DI points at zero terminating byte (etoa2 only)
  4831.  
  4832. Flags affected:       Carry is set if malloc error (etoam only)
  4833.  
  4834. Example of Usage:
  4835.             mov    al, 14        ;Use a total of 14 positions
  4836.             etoam
  4837.             puts
  4838.             putcr
  4839.             free
  4840.  
  4841.  
  4842.  
  4843. Description:    ETOA (2,M) converts the value in the floating point accumulator
  4844.         to a string of characters which represent that value.  These
  4845.         routines use an exponential (scientific notation)
  4846.         representation.  AL contains the field width.  It contains
  4847.         the number of print position to use when outputting the
  4848.         number.  The field width specification works just like Pascal
  4849.         or FORTRAN.  If the number will not fit in the specified
  4850.         field width, ETOA outputs a bunch of "#" characters.
  4851.  
  4852.         ETOA stores the converted string at the address specified by
  4853.         ES:DI upon entry.  There must be at least AL+1 bytes at this
  4854.         address.  It returns with ES:DI pointing at the start of this
  4855.         buffer.
  4856.  
  4857.         ETOA2 works just like ETOA except it does not preserve DI.
  4858.         It returns with DI pointing at the zero terminating byte.
  4859.  
  4860.         ETOAM allocates storage for the string on the heap and returns
  4861.         a pointer to the converted string in ES:DI.
  4862.  
  4863.         Note: this routine preserves the value in the floating point
  4864.         accumulator but it wipes out the value in the floating point
  4865.         operand.
  4866.  
  4867. Include:    stdlib.a
  4868.  
  4869.  
  4870. Routine:  atof
  4871. --------------
  4872.  
  4873. Category:             Floating point Routine
  4874.  
  4875. Registers on entry:   ES:DI points at a string containing the representation
  4876.               of a floating point number in ASCII form.
  4877.  
  4878. Registers on return:  None
  4879.  
  4880. Flags affected:       None
  4881.  
  4882. Example of Usage:
  4883.             les    di, FPStr
  4884.             atof
  4885.  
  4886.  
  4887. Description:    ATOF converts the string pointed at by ES:DI into a floating
  4888.         point value and leaves this value in the floating point
  4889.         accumulator.  Legal floating point values are described
  4890.         by the following regular expression:
  4891.  
  4892.  
  4893.         {" "}* {+ | -} ( ([0-9]+ {"." [0-9]*}) | ("." [0-9]+)}
  4894.                 {(e | E) {+ | -} [0-9] {[0-9]*}}
  4895.  
  4896.  "{}" denote optional items.
  4897.  "|"  denotes OR.
  4898.  "()" groups items together.
  4899.  
  4900.  
  4901.  
  4902. Include:    stdlib.a
  4903.  
  4904.  
  4905.  
  4906. ******************************************************************************
  4907.  
  4908.         File I/O Routines
  4909.  
  4910.            Featuring:
  4911.                - Opening and closing files
  4912.                - Creating new files
  4913.                - Deleting files
  4914.                - Renaming files
  4915.                - File "seeking"
  4916.                - Blocked I/O:
  4917.                    - Reading from files using getc
  4918.                    - Writing to files using putc and puts
  4919.                    - File flushing
  4920.  
  4921. ******************************************************************************
  4922.  
  4923.            Written by:
  4924.  
  4925.                Mark Radleigh
  4926.                &
  4927.  
  4928.                Brian Harvey
  4929.  
  4930. ******************************************************************************
  4931.  
  4932.  
  4933. fcreate
  4934. *    Creates a new file.
  4935. *    If a file already exists with the requested name, it will be deleted
  4936.     and a new one will take its place.
  4937. Inputs: ES:DI- Contains address of the filename for the new file
  4938. Outputs: AX- If no error occured in creating the file, it contains a
  4939.         filehandle number assigned to this file by DOS.
  4940.          If an error has occurred, it contains one of the following error
  4941.         codes:
  4942.          3 - Path not found
  4943.          4 - Too many open files
  4944.          5 - Access denied
  4945.      Carry flag- 0 if no error occured, 1 if error
  4946. Include:    Stdlib.a
  4947. Updated:    6/14/91        First public release
  4948.  
  4949. This routine creates a new file on the specified pathname. If no pathname or
  4950. device is specified, the file will be created in the current working directory.
  4951. If the file has been successfully created (No errors occured!), then this
  4952. routine returns in the ax register a number that is the DOS filehandle for
  4953. this file. Don't lose this value. You will need it when to want to close the
  4954. file (using fclose). Save the ax register in a variable after the routine call
  4955. and move the variable back into the ax register before you call the fclose
  4956. stdlib routine. See documentation for fclose for more information.
  4957.  
  4958. FILEHANDLE NOTICE: The filehandle returned in the ax register is not the true
  4959. DOS filehandle for this file. However, this filehandle is too be used when
  4960. calling the file routines in stdlib. In order to get the true filehandle for a
  4961. certain file, see the documentation for the stdlib routine, DOSHandle
  4962.  
  4963. Example:
  4964.  
  4965.         print
  4966.         db      "What do you desire to create?",0
  4967.         gets                            ;Get filename and store in es:di
  4968.         fcreate                      ;Call routine to create file
  4969.         jc      error                   ;If the carry flag is set,
  4970.                         ;an error has occured.
  4971.         mov     fileptr, ax             ;Save the filehandle stored in
  4972.                         ;the ax register for future
  4973.                         ;use
  4974.  
  4975. fopen
  4976. *    Opens a file for reading or writing.
  4977. *    File I/O depends on value in the al register.
  4978. Inputs: ES:DI- Contains address of the filename for the file to be opened
  4979.     AL- Contains 0 if the file is to be opened for reading.
  4980.         Contains 1 if the file is to be opened for writing.
  4981. Outputs: AX- If no error occured in opening the file, it contains a
  4982.         filehandle number assigned to this file by DOS.
  4983.          If an error has occured, it contains one of the following error
  4984.         codes:
  4985.          2 - File not found
  4986.          4 - Too many open files
  4987.          5 - Access denied
  4988.          12 - Invalid access
  4989.      Carry flag- 0 if no error occured, 1 if error
  4990. Include:    Stdlib.a
  4991. Updated:    6/14/91        First public release
  4992.  
  4993. This routine opens a file for reading or writing using the specified filename
  4994. and directory (any standard DOS file pathway) in ES:DI. Using the stdlib gets
  4995. routine is an excellent and advisable way (Not to mention an easy way!) of
  4996. getting the filename in ES:DI. The user must also move one of two values into
  4997. the al register before calling fopen. To open a file for reading, the al
  4998. register must contain the value 0 and to open a file for writing, the al
  4999. register must contain the value 1. If the file has been successfully opened, a
  5000. filehandle for this file assigned by DOS. Save this filehandle in some sort of
  5001. variable so you can move it back into the ax register when you call the stdlib
  5002. routine fclose to close the file. See documentation for fclose for more
  5003. information. Examine the examples below for a suggested way of saving the
  5004. filehandle (the example uses a variable called fileptr, but the name is
  5005. arbritary).
  5006.  
  5007. FILEHANDLE NOTICE: The filehandle returned in the ax register is not the true
  5008. DOS filehandle for this file. However, this filehandle is too be used when
  5009. calling the file routines in stdlib. In order to get the true filehandle for a
  5010. certain file, see the documentation for the stdlib routine, DOSHandle
  5011.  
  5012. NOTICE FOR MULTIPLE OPEN FILES: fopen, along with fcreate and fclose, allows the
  5013.                 user have up to 10 files open at the same time.
  5014.                 In order to keep track of all the filehandles of
  5015.                 these open files, it is suggested that a
  5016.                 separate variable for the filehandle of each
  5017.                 of the open files be used to keep track of the
  5018.                 handles.
  5019.  
  5020. Example for opening mulitple files (same theory applies with fcreate):
  5021.         print
  5022.         db      "What do you desire to open?",0
  5023.         gets                            ;Get filename and store in es:di
  5024.         mov     al, 1                   ;1 so the file will be opened
  5025.                         ;for writing
  5026.         fopen                        ;Call routine to open file
  5027.         jc      error                   ;If the carry flag is set,
  5028.                         ;an error has occured, so quit!
  5029.         mov     fileptr, ax             ;Save the filehandle stored in
  5030.                         ;the ax register for future
  5031.                         ;use
  5032.         print
  5033.         db    "What is the 2nd file you wish to open?",0
  5034.         gets
  5035.         mov    al, 1
  5036.         fopen                ;Open 2nd file for writing
  5037.         jc    error            ;Error??
  5038.         mov    fileptr2,ax        ;Save the filehandle for the 2nd
  5039.                         ;open file in a separate
  5040.                         ;variable
  5041.  
  5042.  
  5043. Warning:  If the file the user wishes to open already exists and the user wants
  5044.       to open it for writing, then the data written to the file will
  5045.       overwrite the pre-exeisting data. See docs for fseek to overcome
  5046.       this problem.
  5047.  
  5048. Example:
  5049.  
  5050. ;Open a file for writing
  5051.         print
  5052.         db      "What do you desire to open?",0
  5053.         gets                            ;Get filename and store in es:di
  5054.         mov    al, 1            ;1 so the file will be opened
  5055.                         ;for writing
  5056.  
  5057.  
  5058.         fopen                        ;Call routine to open file
  5059.         jc      error                   ;If the carry flag is set,
  5060.                         ;an error has occured, so quit!
  5061.         mov     fileptr, ax             ;Save the filehandle stored in
  5062.                         ;the ax register for future
  5063.                         ;use
  5064.  
  5065. ;Open a file for reading
  5066.         print
  5067.         db      "What do you desire to open?",0
  5068.         gets                            ;Get filename and store in es:di
  5069.         mov     al, 0                   ;0 so the file will be opened
  5070.                         ;for reading
  5071.                 fopen                        ;Call routine to open file
  5072.                 jc      error                   ;If the carry flag is set,
  5073.                                                 ;an error has occured, so quit!
  5074.         mov     fileptr, ax             ;Save the filehandle stored in
  5075.                                                 ;the ax register for future
  5076.                                                 ;use
  5077.  
  5078. fclose
  5079. *    Closes an open file
  5080. *    Filehandle for file to be closed needs to be in the ax register
  5081. Input: AX- Contains the filehandle variable of the file to close.
  5082. Outputs: AX- If carry flag is set (error occured), then ax contains an error
  5083.         code.
  5084.          If an error has occured, it contains the following error code:
  5085.         6 - Invalid file handle
  5086.         10 - Trouble with FREE (memory freeing routine)
  5087.      Carry flag- 0 if no error occured, 1 if error.
  5088. Include:    Stdlib.a
  5089. Updated:    6/14/91        First public release
  5090.  
  5091. This routine closes an open file. Once the file is closed no I/O processes
  5092. can be made on the file. Before calling the routine, fclose, the user must
  5093. move into the ax register the filehandle assigned to this file when the file
  5094. was opened or created. The only error that can occur is if the user moved into
  5095. the ax register a filehandle that does not belong to one of the opened files.
  5096. The following example demonstrates how to close a file that was opened in one of
  5097. the fopen examples or the file that was created in the fcreate example, whose
  5098. filehandle was saved in variable called fileptr.
  5099. Example:
  5100.                 mov     ax, fileptr        ;Move the DOS filehandle into
  5101.                         ;the ax register before
  5102.                         ;calling routine
  5103.                 fclose                ;Close the file
  5104.                 cmp     ax, 6            ;If the filehandle was an
  5105.                         ;invalid filehandle jump to
  5106.                         ;user's code for error's
  5107.                 je      error
  5108. ;The following code is a continuation in the case that multiple files are
  5109. ;open. The code close the second open file.
  5110.         mov    ax, fileptr2
  5111.         fclose
  5112.         cmp    ax, 6
  5113.         je    error
  5114.  
  5115. fwriteon
  5116. *    Turns on the write to file mode.
  5117. *    Redirects the ouput of stdlib routines putc and puts to a open file
  5118. Input: AX- Contains the filehandle of which open file to write data to.
  5119. Outputs: AX- If an error occurs in attempting to write to a file, ax will
  5120.         contain one of the following error codes:
  5121.           5 - Accessed denied
  5122.           6 - Invalid handle
  5123.      Carry flag- 0 if no error occured, 1 if error.
  5124. Include:    Stdlib.a
  5125. Updated:    6/14/91        First public release
  5126.  
  5127. This routine turns the write to disk mode on. In other words, it redirects the
  5128. output of the stdlib putc routine so that instead of writing data to the screen,
  5129. the data is written to the file whose filehandle is in the ax register when
  5130. fwriteon is called. The routine that replaces the output device of putc's ouput
  5131. actually uses what is known as Blocked I/O. Instead of writing one character
  5132. to the file each time the user calls getc, each character is stored in a buffer
  5133. in memory. When the buffer contains 256 characters, that buffer is written to
  5134. the file as a block. The buffer is then cleared and more characters can be read
  5135. with getc. Using blocked I/O is a lot faster than one character at a time. Along
  5136. with getc, the stdlib routine gets' ouput is also redirected during fwriteon
  5137. mode, since in the stdlib, gets actually just calls getc many times.
  5138.  
  5139. Example:
  5140. ;This code would appear in a program after a file has been created or opened
  5141. ;for "gets"
  5142.         mov    ax, fileptr        ;Move into ax filehandle of
  5143.                         ;file to write to
  5144.                 fwriteon                     ;Call function to redirect
  5145.                                                 ;the output of putc and puts
  5146.         puts
  5147.         fwriteoff            ;Turn off write to disk mode
  5148.         puts
  5149. ;The puts must appear after the fwriteoff command because gets automatically
  5150. ;writes whatever is in ES:DI to the screen (or in this case the file). The puts
  5151. ;appearing after the writeoff, prints whatever is at ES:DI to the screen. If
  5152. ;the puts were to appear in the writeoon mode, the string at ES:DI would be
  5153. ;written to the file twice
  5154.  
  5155. Example:
  5156. ;This code would appear in a program after a file has been created or opened
  5157. ;for "getc"
  5158.         mov    ax, fileptr        ;Move into ax filehandle of
  5159.                         ;file to write to
  5160.         fwriteon                 ;Call function to redirect
  5161.                         ;the output of putc and puts
  5162.         getc
  5163.         putc
  5164.         fwriteoff
  5165. ;Unlike in the previous example, getc and putc may both appear in the writeon
  5166. ;mode. The getc will get a character from the keyboard and store it in the al
  5167. ;register. Putc will then write whatever is in the al register to the
  5168. ;specified open file. In order for the user to see what character they typed
  5169. ;in, in the previous example, a putc should appear after the fwriteoff call.
  5170. ;Since fwriteoff redirects the putc ouput back to normal (See docs for fwriteoff
  5171. ;for more info) the character in al will be put on the screen.
  5172.  
  5173. fwriteoff
  5174. *    Turns off the write to file mode
  5175. *    Redirects the output of putc back to normal (the screen!)
  5176.         mode.
  5177. Include:    Stdlib.a
  5178. Updated:    6/14/91        First public release
  5179.  
  5180. This routines changes or redirects the ouput of stdlib's putc back to normal.
  5181. In other words, since the routine fwriteon made the ouput go to a disk file,
  5182. changing it back to normal means that after this routine is called, all putc's
  5183. used will print whatever is in the al register to the screen.
  5184.  
  5185. Example:
  5186. ;This example gets a character from the keyboard, prints to a disk file and then
  5187. ;prints to the screen the character in the al register that was entered.
  5188.         mov    ax, fileptr        ;Move into ax filehandle of
  5189.                         ;file to write to
  5190.         fwriteon                 ;Call function to redirect
  5191.                         ;the output of putc and puts
  5192.         getc                ;Get character and store in al
  5193.         putc                ;Print character in al to file
  5194.         fwriteoff            ;Change ouput of putc back to
  5195.                         ;normal
  5196.         putc                ;Prints character in al to
  5197.                         ;screen
  5198. fflush
  5199. *    Flushes the buffer in an opened write file to that file
  5200. Inputs:    AX- Contains Stdlib filehandle of file whose buffer is to be flushed
  5201. Outputs: None.
  5202. Include:    Stdlib.a
  5203. Updated:        6/14/91         First public release
  5204.  
  5205. This routine takes all data from the buffer associated with the Stdlib
  5206. filehandle passed in AX and writes it to the file. It then clears the buffer.
  5207. NOTE: This routine is automatically called on by Fclose.
  5208.  
  5209. freadon
  5210. *    Turns on the read from file mode
  5211. *    Changes the source of the input for the stdlib function getc
  5212. Input:    AX- Contains the filehandle of which open file to read data from.
  5213. Output: AL- Contains a character read from the specified file.
  5214.     AX- If an error occurs in attempting to read from a file, ax will
  5215.         contain one of the following error codes:
  5216.           5 - Access denied
  5217.           6 - Invalid handle
  5218.           8 - EOF
  5219.     Carry flag- 0 if no error occured, 1 if error.
  5220. Include:    Stdlib.a
  5221. Updated:    6/14/91        First public release
  5222.  
  5223. This routine turns the read from file mode on. It redirects the source from
  5224. which stdlib's getc routine gets its "character" from. Instead of getting the
  5225. character from the keyboard, the redirected getc reads a character from a opened
  5226. file. Actually, this routine uses the blocked I/O idea discussed in the writeon
  5227. documentation. This routine when called for the first time, meaning the buffer
  5228. for the current file to be read from is clear, will read it 256 characters from
  5229. (If there is that many) a file and store it in the buffer. The first character
  5230. in the buffer is then put in the al register for the user to then use for
  5231. whatever they wish. The next time the user calls getc (without calling the
  5232. freadoff rotuine yet) the next character in the buffer will be stored in the al
  5233. register. When the buffer is empty, another 256 bytes will be read into it. When
  5234. the routine freadoff is called, any getc routines called after that will get
  5235. a character from the keyboard.
  5236.  
  5237. Example:
  5238.         mov    ax, fileptr        ;Move the filehandle of the
  5239.                         ;file to read from into ax
  5240.         freadon                ;Turn on read mode!
  5241.         mov    cx, 10            ;Set up loop to read 10
  5242.                         ;characters from a file and
  5243.                         ;print them to the screen
  5244. loop1:        getc                ;Get character from buffer and
  5245.                         ;store in al
  5246.         jc    error            ;If error in reading from file
  5247.                         ;jump to user's code for
  5248.                         ;handling code
  5249.         putc                ;Print character in al to the
  5250.                         ;screen
  5251.         loop    loop1
  5252.         freadoff            ;turn read mode off from this
  5253.                         ;file
  5254.  
  5255. freadoff
  5256. *    Turns off the read from file mode
  5257. *    Redirects the source of the data for stdlib's getc routine back to
  5258.     normal
  5259.  
  5260. This routine changes the source from which stdlib's getc routine gets its
  5261. "character" from back to normal. After calling this routine, instead of reading
  5262. characters from the disk, using blocked I/O, the getc routine will get
  5263. it's "character" from the keyboard.
  5264.  
  5265. For code example of how to use freadoff, see the example of code above for
  5266. freadon.
  5267.  
  5268.  
  5269. fseek
  5270. *    Moves the file pointer of a file to anywhere in the file
  5271. Inputs:    SI- Contains the filehandle variable of the file to be used, or "seeked"
  5272.     AL- Contains the offset from where to start the file seeking.
  5273.         0 - Seek from the begining of the file.
  5274.         1 - Seek from current pointer position
  5275.         2 - Seek backwards from the end of file
  5276.     CX:DX- Distance to move in file, in bytes.
  5277. Outputs: DX:AX- Contains the new file position if no error
  5278.      AX- One of the following error codes if an error occured while
  5279.         "seeking":
  5280.           1 - Invalid function
  5281.           6 - Invalid handle
  5282.     Carry flag- 0 if no error occured, 1 if error.
  5283. Include:    Stdlib.a
  5284. Updated:    6/14/91        First public release
  5285.  
  5286. This routine allows the user the move the file pointer to any position within
  5287. a file. You can not move backwards in a file by having a negative value in
  5288. CX:DX. The value in CX:DX must be an unsigned integer. 
  5289.  
  5290. Example:
  5291.         mov    si, fileptr        ;Move the filehandle of the
  5292.                         ;file to be seeked
  5293.         mov    al, 0            ;Start moving pointer from
  5294.                         ;beginning of file
  5295.         xor    cx, cx            ;Clear the cx register
  5296.         mov    dx, 10            ;Move file pointer 10 bytes
  5297.                         ;into file
  5298.         fseek                ;Seek!!!
  5299.         jc    error            ;Jump to error code if error
  5300.  
  5301. To find out where the file pointer currently is in the file, first xor cx and 
  5302. dx registers and call fseek. It will return in DX:AX the file pointer's
  5303. position.
  5304.         mov    si, fileptr        ;Move the filehandle of the
  5305.                         ;file to be seeked
  5306.         mov    al, 1            ;Start moving pointer from
  5307.                         ;the current position
  5308.         xor    cx, cx            ;Clear the cx register
  5309.         xor    dx, dx            ;Clear the dx register
  5310.         fseek                ;Seek!!!
  5311.         jc    error            ;Jump to error code if error
  5312.                         ;else DX:AX contains the current
  5313.                         ;File pointer position.
  5314.  
  5315.  
  5316. DOSHandle
  5317. *    Returns in the ax register the true DOS filehandle for a file
  5318. Input:    AX- Contains the filehandle for the file given to the user from
  5319.         stdlib routine, fopen or fcreate
  5320. Ouputs:    AX- Contains the true filehandle given to the requested file by DOS
  5321.     AX- If an error occured, it contains the following error code:
  5322.           1 - Invalid pseudo-filehandle
  5323.     Carry flag- 0 if no error occured, 1 if error.
  5324. Include:    Stdlib.a
  5325. Updated:    6/14/91        First public release
  5326.  
  5327. This routine returns in the ax register the true filehandle variable given by
  5328. DOS for a particular file. The filehandle returned when calling the stdlib
  5329. functions, fcreate and fopen, is not the true filehandle for the file used
  5330. in those routines. The value returned is a value created by the routines, which
  5331. stores the filehandles for multiple files in a structure in memory. The value
  5332. returned from those functions is actually the index into the structure to the
  5333. real filehandle for the file. This function, DOSHandle, returns from this
  5334. structure in memory the actual filehandle for a file that has been opened. 
  5335. NOTICE: This routine is only useful to those who need to know the real
  5336. filehandle of a file that has been created or opened with fopen or fcreate. For
  5337. those who will only be using the File I/O routines provided in stdlib then
  5338. this routine will be of no importance. It is provided only for advanced assembly
  5339. language programmers who with to do other things with files and need to know
  5340. their real filehandle values.
  5341.  
  5342. Example:
  5343.         mov    ax, fileptr        ;Move into ax the filehandle
  5344.                         ;given to the user file fopen
  5345.                         ;or fcreate
  5346.         DOSHandle            ;Get the true filehandle for
  5347.                         ;a file and store it in the
  5348.                         ;ax register
  5349.         mov    truehandle, ax
  5350.  
  5351. frename
  5352. *    Renames a file
  5353. Input:    DX:SI- Contains the original pathname of the file
  5354.     ES:DI- Contains the new pathname of the file
  5355. Ouputs:    AX- Contains one of the following error codes if an error occured:
  5356.           2 - File not found
  5357.           5 - Access denied
  5358.           17 - Not the same device
  5359.     Carry flag- 0 if no error occured, 1 if error.
  5360. Include:    Stdlib.a
  5361. Updated:    6/14/91        First public release
  5362.  
  5363. This routine renames the file whose name appears in a string at DX:SI with the
  5364. name that appears at the string pointed at by ES:DI. If an error occurs, then
  5365. an appropriate error code appears in the ax register.
  5366.  
  5367. Example:
  5368.         print
  5369.         db    "Enter the source filename: ",0
  5370.         gets
  5371.         mov    dx, es
  5372.         mov    si, di
  5373.         print
  5374.         db    cr, lf, "Enter the new filename: ",0
  5375.         gets
  5376.         frename
  5377.         jc    error
  5378.  
  5379. fdel
  5380. *    Deletes a file
  5381. Input: ES:DI- Contains the address of zero terminated pathname of file
  5382. Output: AX- Contains one of the following error codes if an error occured:
  5383.           2 - File not found
  5384.           5 - Access denied
  5385.         Carry flag- 0 if no error occured, 1 if error.
  5386. Include:        Stdlib.a
  5387. Updated:        6/14/91         First public release
  5388.  
  5389. This routine deletes the filename that is in the string that ES:DI points to.
  5390.  
  5391. Example:
  5392.         print
  5393.         db    "Name of file to delete?",0
  5394.         gets
  5395.         fdel                ;Delete the file!
  5396.         jc    error            ;Jump to error code if an error
  5397.  
  5398.  
  5399.  
  5400.  
  5401. ======================
  5402. Miscellaneous Routines
  5403. ======================
  5404.  
  5405. This routines either defy categorization, or they haven't been properly
  5406. organized yet.
  5407.  
  5408. Mostly (like the rest of this library) they have simply been stuck here
  5409. until somebody gets the time to reorganize *everything*.
  5410.  
  5411.  
  5412.  
  5413.  
  5414. Routine:  Random
  5415. ----------------
  5416.  
  5417. Author:              Unknown.  Copied off a file on one of the networks,
  5418.               tweaked, and added to the library.  Any info on the
  5419.               original author would be appreciated.
  5420.  
  5421. Category:             Miscellaneous
  5422.  
  5423. Registers on entry:   None
  5424.  
  5425. Registers on return:  AX-    Contains random number
  5426.  
  5427. Flags affected:       None
  5428.  
  5429. Example of Usage:
  5430.             random    ;Generate random number in AX
  5431.             puti    ;Print the random number.
  5432.  
  5433.  
  5434. Description:    
  5435.  
  5436.  This routine computes a 16-bit random number each time you call it.  It
  5437. returns the random number in the AX register.  You may treat this as a signed
  5438. or unsigned value as it utilizes all 16 bits.  This code uses an internal
  5439. table of seed values.  If you are interested in producing repeatable sequences
  5440. of random numbers, please look at the source listings for this file.
  5441.  
  5442.  If you are interested in producing truly random values (well, closer than you
  5443. will get from this code by calling it right off the bat) look at the randomize
  5444. routine which tweaks the seed table based on the current time of day clock
  5445. value.
  5446.  
  5447. Include:    stdlib.a
  5448.  
  5449.  
  5450. Routine:  Randomize
  5451. -------------------
  5452.  
  5453. Author:              Unknown.  Copied off a file on one of the networks,
  5454.               tweaked, and added to the library.  Any info on the
  5455.               original author would be appreciated.
  5456.  
  5457. Category:             Miscellaneous
  5458.  
  5459. Registers on entry:   None
  5460.  
  5461. Registers on return:  None
  5462.  
  5463. Flags affected:       None
  5464.  
  5465. Example of Usage:
  5466.             randomize    ;Randomize the seeds.
  5467.             random        ;Get a brand new random number
  5468.             puti        ;Print it
  5469.  
  5470. Description:    
  5471.  
  5472. Random's internal seed table is hard coded.  It was designed to produce a
  5473. sequence of random numbers with a very long period.  However, each time you
  5474. run a program using Random, it will generate the exact same sequence of
  5475. random numbers.  This could be distressing, for example, in a game where
  5476. after a while the player(s) could memorize some sequence of events based
  5477. on the random number generator.
  5478.  
  5479.  Randomize uses the time of day clock value to scramble the internal random
  5480. seed table.  If you call randomize before using random the first time, you
  5481. will generally get a different sequence of random numbers each time you
  5482. run the program.
  5483.  
  5484.  Note that it is dangerous to call randomize more than once inside any program.
  5485. The time of day clock is not a random source when invoked fairly often.
  5486. Furthermore, once the seeds are randomized, random does a pretty good job of
  5487. randomizing the results.
  5488.  
  5489. Include:    stdlib.a
  5490.  
  5491.  
  5492. Routine:  cpuid
  5493. ---------------
  5494.  
  5495. Author:              Original implementation was supplied by Intel Corp.
  5496.               Various modifications were made for inclusion into
  5497.               the UCR Standard Library.
  5498.  
  5499. Category:             Miscellaneous
  5500.  
  5501. Registers on entry:   None
  5502.  
  5503. Registers on return:  AX-    Contains processor ID (86, 286, 386, or
  5504.                 486.  Note 8088=86).
  5505.  
  5506.               BX-    Contains coprocessor ID (87, 286, 387,
  5507.                 or 487).  Note that a true 486 will have
  5508.                 an 80487 built-in, 486sx chips, however, will
  5509.                 not.
  5510.  
  5511. Flags affected:       None
  5512.  
  5513. Example of Usage:
  5514.             cpuid
  5515.             cmp    ax, 8086    ;Is this an 8086?
  5516.  
  5517. Description:    
  5518.  
  5519.  For those programs which absolutely need to know the CPU in use, CPUID does
  5520. a reasonable job (in DOS real mode) of figuring this out for you.  As with
  5521. all CPU identification routines, there are bound to be some problems with this
  5522. one when operating in protected mode. But for normal DOS applications it
  5523. appears to work great.  This routine came straight from the horse's mouth
  5524. (Intel Corporation) so you can place a little more faith in it than most that
  5525. are floating around.  Intel's blessing doesn't guarantee that this routine
  5526. is perfect, though; always keep that in mind.
  5527.  
  5528. Include:    stdlib.a
  5529.